Skip to content

Commit

Permalink
unfinished work
Browse files Browse the repository at this point in the history
  • Loading branch information
JohanEngelen committed Apr 23, 2016
1 parent 9e80617 commit e81cefd
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 59 deletions.
15 changes: 12 additions & 3 deletions gen/ldctraits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

#include "gen/irstate.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include <iostream>

// TODO: move this to a D interfacing helper file
struct Dstring {
Expand All @@ -21,7 +23,14 @@ Dstring traitsGetTargetCPU() {
return {cpu.data(), cpu.size()};
}

Dstring traitsGetTargetFeatures() {
auto features = gTargetMachine->getTargetFeatureString();
return {features.data(), features.size()};
bool traitsTargetHasFeature(Dstring feature) {
auto feat = llvm::StringRef(feature.ptr, feature.len);

auto *mcinfo = const_cast<llvm::MCSubtargetInfo*>( gTargetMachine->getMCSubtargetInfo() );
auto savedFeatbits = mcinfo->getFeatureBits();
auto newFeatbits = mcinfo->ApplyFeatureFlag(feat);
bool featureFound = (savedFeatbits == newFeatbits);
mcinfo->setFeatureBits(savedFeatbits);

return featureFound;
}
59 changes: 3 additions & 56 deletions gen/ldctraits.d
Original file line number Diff line number Diff line change
Expand Up @@ -29,36 +29,7 @@ extern(C++) struct Dstring
};

extern(C++) Dstring traitsGetTargetCPU();
extern(C++) Dstring traitsGetTargetFeatures();

// Parses the comma separated features into a (positive-only) array of feature strings
private const(char)[][] traitsGetTargetFeaturesArray()
{
auto llvmfeatures = traitsGetTargetFeatures();

const(char)[][] result;
size_t pos;
while (pos < llvmfeatures.len)
{
// Find out whether this is a positive or negative feature
bool positive = llvmfeatures.ptr[pos++] == '+';
size_t start = pos;
// Walk to the next comma or end-of-string
while (pos < llvmfeatures.len)
{
if (llvmfeatures.ptr[pos] == ',')
break;
pos++;
}
if (positive)
{
result ~= llvmfeatures.ptr[start..pos];
}
pos++;
}

return result;
}
extern(C++) bool traitsTargetHasFeature(Dstring feature);

Expression semanticTraitsLDC(TraitsExp e, Scope* sc)
{
Expand All @@ -75,22 +46,6 @@ Expression semanticTraitsLDC(TraitsExp e, Scope* sc)
auto se = new StringExp(e.loc, cast(void*)cpu.ptr, cpu.len);
return se.semantic(sc);
}
if (e.ident == Id.targetFeatures)
{
if (arg_count != 0)
{
e.warning("ignoring arguments for __traits %s", e.ident.toChars());
}

auto features = traitsGetTargetFeaturesArray();
auto exps = new Expressions();
foreach(feat; features)
{
exps.push(new StringExp(e.loc, cast(void*)feat.ptr, feat.length));
}
auto tup = new TupleExp(e.loc, exps);
return tup.semantic(sc);
}
if (e.ident == Id.targetHasFeature)
{
if (arg_count != 1)
Expand Down Expand Up @@ -120,16 +75,8 @@ Expression semanticTraitsLDC(TraitsExp e, Scope* sc)
return new ErrorExp();
}

auto searchfor = se.string[0..se.len];

auto features = traitsGetTargetFeaturesArray();
foreach(feat; features)
{
if (feat == searchfor)
return new IntegerExp(e.loc, 1, Type.tbool);
}
// Feature not found
return new IntegerExp(e.loc, 0, Type.tbool);
auto featureFound = traitsTargetHasFeature(Dstring(se.toPtr(), se.len));
return new IntegerExp(e.loc, featureFound ? 1 : 0, Type.tbool);
}
return null;
}
23 changes: 23 additions & 0 deletions tests/codegen/target_traits.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Tests LDC-specific target __traits

// RUN: %ldc -mcpu="haswell" -mattr="-sse" -c %s

import std.algorithm;
import std.stdio;

void main()
{
/* static assert(__traits(targetCPU) == "haswell");
static assert(!__traits(targetHasFeature, "sse"));
static assert(__traits(targetHasFeature, "sse3"));
static assert(__traits(targetHasFeature, "sse4.1"));
static assert(!__traits(targetHasFeature, "sse4"));
static assert(!__traits(targetHasFeature, "sse4a"));
static assert(any!q{a = "sse4.1"}([__traits(targetFeatures)]));
*/
writeln("CPU = ", __traits(targetCPU));
// writeln("Features = ", [__traits(targetFeatures)]);
// writeln("Has 'sse3' = ", __traits(targetHasFeature, "sse3"));
writeln("Has 'sse4' = ", __traits(targetHasFeature, "sse4"));
// writeln("Has 'sse4.1' = ", any!q{a = "sse4.1"}([__traits(targetFeatures)]));
}

0 comments on commit e81cefd

Please sign in to comment.