Skip to content

Commit 962f60a

Browse files
committed
Add ExtAsmStatement implementation
1 parent a203f13 commit 962f60a

9 files changed

Lines changed: 496 additions & 0 deletions

File tree

src/ddmd/dinterpret.d

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,18 @@ public:
666666
// we can't compile asm statements
667667
}
668668

669+
static if (IN_GCC)
670+
{
671+
override void visit(ExtAsmStatement s)
672+
{
673+
debug (LOGCOMPILE)
674+
{
675+
printf("%s ExtAsmStatement::ctfeCompile\n", s.loc.toChars());
676+
}
677+
// we can't compile extended asm statements
678+
}
679+
}
680+
669681
void ctfeCompile(Statement s)
670682
{
671683
s.accept(this);
@@ -1998,6 +2010,25 @@ public:
19982010
result = CTFEExp.cantexp;
19992011
}
20002012

2013+
static if (IN_GCC)
2014+
{
2015+
override void visit(ExtAsmStatement s)
2016+
{
2017+
debug (LOG)
2018+
{
2019+
printf("%s ExtAsmStatement::interpret()\n", s.loc.toChars());
2020+
}
2021+
if (istate.start)
2022+
{
2023+
if (istate.start != s)
2024+
return;
2025+
istate.start = null;
2026+
}
2027+
s.error("extended asm statements cannot be interpreted at compile time");
2028+
result = CTFEExp.cantexp;
2029+
}
2030+
}
2031+
20012032
override void visit(ImportStatement s)
20022033
{
20032034
debug (LOG)

src/ddmd/hdrgen.d

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,67 @@ public:
685685
buf.writenl();
686686
}
687687

688+
static if (IN_GCC)
689+
{
690+
override void visit(ExtAsmStatement s)
691+
{
692+
buf.writestring ("gcc asm { ");
693+
694+
if (s.insn)
695+
buf.writestring (s.insn.toChars());
696+
697+
buf.writestring (" : ");
698+
699+
if (s.args)
700+
{
701+
for (size_t i = 0; i < s.args.dim; i++)
702+
{
703+
Identifier name = (*s.names)[i];
704+
Expression constr = (*s.constraints)[i];
705+
Expression arg = (*s.args)[i];
706+
707+
if (name)
708+
{
709+
buf.writestring ("[");
710+
buf.writestring (name.toChars());
711+
buf.writestring ("] ");
712+
}
713+
714+
if (constr)
715+
{
716+
buf.writestring (constr.toChars());
717+
buf.writestring (" ");
718+
}
719+
720+
if (arg)
721+
buf.writestring (arg.toChars());
722+
723+
if (i < s.outputargs - 1)
724+
buf.writestring (", ");
725+
else if (i == s.outputargs - 1)
726+
buf.writestring (" : ");
727+
else if (i < s.args.dim - 1)
728+
buf.writestring (", ");
729+
}
730+
}
731+
732+
if (s.clobbers)
733+
{
734+
buf.writestring (" : ");
735+
for (size_t i = 0; i < s.clobbers.dim; i++)
736+
{
737+
Expression clobber = (*s.clobbers)[i];
738+
buf.writestring (clobber.toChars());
739+
if (i < s.clobbers.dim - 1)
740+
buf.writestring (", ");
741+
}
742+
}
743+
744+
buf.writestring ("; }");
745+
buf.writenl();
746+
}
747+
}
748+
688749
override void visit(ImportStatement s)
689750
{
690751
foreach (imp; *s.imports)

src/ddmd/parse.d

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5973,6 +5973,20 @@ final class Parser(AST) : Lexer
59735973
error("matching `}` expected, not end of file");
59745974
goto Lerror;
59755975

5976+
static if (IN_GCC)
5977+
{
5978+
case TOKlparen:
5979+
case TOKstring:
5980+
// If the first token is a string or '(', parse as extended asm.
5981+
if (!toklist)
5982+
{
5983+
s = parseExtAsm(stc);
5984+
statements.push(s);
5985+
continue;
5986+
}
5987+
goto Ldefault;
5988+
}
5989+
59765990
default:
59775991
Ldefault:
59785992
*ptoklist = Token.alloc();
@@ -6019,6 +6033,228 @@ final class Parser(AST) : Lexer
60196033
return s;
60206034
}
60216035

6036+
static if (IN_GCC)
6037+
{
6038+
/***********************************
6039+
* Parse list of extended asm input or output operands.
6040+
* ExtAsmOperand:
6041+
* [Identifier] StringLiteral (Identifier), ...
6042+
*/
6043+
int parseExtAsmOperands(AST.Expressions* args, AST.Identifiers* names, AST.Expressions* constraints)
6044+
{
6045+
int numargs = 0;
6046+
6047+
while (1)
6048+
{
6049+
AST.Expression arg;
6050+
Identifier name;
6051+
AST.Expression constraint;
6052+
6053+
switch (token.value)
6054+
{
6055+
case TOKsemicolon:
6056+
case TOKcolon:
6057+
case TOKeof:
6058+
return numargs;
6059+
6060+
case TOKlbracket:
6061+
nextToken();
6062+
if (token.value == TOKidentifier)
6063+
{
6064+
name = token.ident;
6065+
nextToken();
6066+
}
6067+
else
6068+
{
6069+
error("expected identifier after '['");
6070+
return numargs;
6071+
}
6072+
check(TOKrbracket);
6073+
// fall through
6074+
6075+
default:
6076+
constraint = parsePrimaryExp();
6077+
if (constraint.op != TOKstring)
6078+
{
6079+
error(constraint.loc, "expected constant string constraint for operand, not '%s'", constraint.toChars());
6080+
goto Lerror;
6081+
}
6082+
arg = parseAssignExp();
6083+
6084+
args.push(arg);
6085+
names.push(name);
6086+
constraints.push(constraint);
6087+
numargs++;
6088+
6089+
if (token.value == TOKcomma)
6090+
nextToken();
6091+
break;
6092+
6093+
}
6094+
}
6095+
Lerror:
6096+
while (token.value != TOKrcurly &&
6097+
token.value != TOKsemicolon &&
6098+
token.value != TOKeof)
6099+
nextToken();
6100+
6101+
return numargs;
6102+
}
6103+
6104+
/***********************************
6105+
* Parse list of extended asm clobbers.
6106+
* ExtAsmClobbers:
6107+
* StringLiteral, ...
6108+
*/
6109+
AST.Expressions *parseExtAsmClobbers()
6110+
{
6111+
AST.Expressions *clobbers;
6112+
6113+
while (1)
6114+
{
6115+
AST.Expression clobber;
6116+
6117+
switch (token.value)
6118+
{
6119+
case TOKsemicolon:
6120+
case TOKcolon:
6121+
case TOKeof:
6122+
return clobbers;
6123+
6124+
case TOKstring:
6125+
clobber = parseAssignExp();
6126+
if (!clobbers)
6127+
clobbers = new AST.Expressions();
6128+
clobbers.push(clobber);
6129+
6130+
if (token.value == TOKcomma)
6131+
nextToken();
6132+
break;
6133+
6134+
default:
6135+
error("expected constant string constraint for clobber name, not '%s'", token.toChars());
6136+
goto Lerror;
6137+
}
6138+
}
6139+
Lerror:
6140+
while (token.value != TOKrcurly &&
6141+
token.value != TOKsemicolon &&
6142+
token.value != TOKeof)
6143+
nextToken();
6144+
6145+
return clobbers;
6146+
}
6147+
6148+
/***********************************
6149+
* Parse list of extended asm goto labels.
6150+
* ExtAsmGotoLabels:
6151+
* Identifier, ...
6152+
*/
6153+
AST.Identifiers *parseExtAsmGotoLabels()
6154+
{
6155+
AST.Identifiers *labels;
6156+
6157+
while (1)
6158+
{
6159+
switch (token.value)
6160+
{
6161+
case TOKsemicolon:
6162+
case TOKeof:
6163+
return labels;
6164+
6165+
case TOKidentifier:
6166+
if (!labels)
6167+
labels = new AST.Identifiers();
6168+
labels.push(token.ident);
6169+
6170+
if (nextToken() == TOKcomma)
6171+
nextToken();
6172+
break;
6173+
6174+
default:
6175+
error("expected identifier for goto label name, not '%s'", token.toChars());
6176+
goto Lerror;
6177+
}
6178+
}
6179+
Lerror:
6180+
while (token.value != TOKrcurly &&
6181+
token.value != TOKsemicolon &&
6182+
token.value != TOKeof)
6183+
nextToken();
6184+
6185+
return labels;
6186+
}
6187+
6188+
/***********************************
6189+
* Parse an extended asm statement.
6190+
* ExtAsmStatement:
6191+
* asm { StringLiterals [ : InputOperands [ : OutputOperands [ : Clobbers [ : GotoLabels ] ] ] ] }
6192+
*/
6193+
6194+
AST.Statement parseExtAsm(StorageClass stc)
6195+
{
6196+
AST.Expressions *args;
6197+
AST.Identifiers *names;
6198+
AST.Expressions *constraints;
6199+
int outputargs = 0;
6200+
AST.Expressions *clobbers;
6201+
AST.Identifiers *labels;
6202+
Loc loc = token.loc;
6203+
6204+
AST.Expression insn = parseExpression();
6205+
if (token.value == TOKsemicolon)
6206+
goto Ldone;
6207+
6208+
for (int section = 0; section < 4; ++section)
6209+
{
6210+
check(TOKcolon);
6211+
6212+
final switch (section)
6213+
{
6214+
case 0:
6215+
if (!args)
6216+
{
6217+
args = new AST.Expressions();
6218+
constraints = new AST.Expressions();
6219+
names = new AST.Identifiers();
6220+
}
6221+
outputargs = parseExtAsmOperands(args, names, constraints);
6222+
break;
6223+
6224+
case 1:
6225+
parseExtAsmOperands(args, names, constraints);
6226+
break;
6227+
6228+
case 2:
6229+
clobbers = parseExtAsmClobbers();
6230+
break;
6231+
6232+
case 3:
6233+
labels = parseExtAsmGotoLabels();
6234+
break;
6235+
}
6236+
6237+
switch (token.value)
6238+
{
6239+
case TOKsemicolon:
6240+
goto Ldone;
6241+
6242+
case TOKeof:
6243+
error("matching '}' expected, not end of file");
6244+
goto Ldone;
6245+
6246+
default:
6247+
continue;
6248+
}
6249+
}
6250+
Ldone:
6251+
check(TOKsemicolon);
6252+
6253+
return new AST.ExtAsmStatement(loc, stc, insn, args, names,
6254+
constraints, outputargs, clobbers, labels);
6255+
}
6256+
}
6257+
60226258
/*****************************************
60236259
* Parse initializer for variable declaration.
60246260
*/

0 commit comments

Comments
 (0)