diff gen/asmstmt.cpp @ 756:a58784e0f035

Merge wilsonk's x86-64 inline assembly.
author Christian Kamm <kamm incasoftware de>
date Sat, 08 Nov 2008 22:29:19 +0100
parents 26fce59fe80a
children f04dde6e882c
line wrap: on
line diff
--- a/gen/asmstmt.cpp	Sat Nov 08 11:34:35 2008 +0100
+++ b/gen/asmstmt.cpp	Sat Nov 08 22:29:19 2008 +0100
@@ -57,13 +57,13 @@
     char *   insnTemplate;
     unsigned insnTemplateLen;
     Array    args; // of AsmArg
-    unsigned moreRegs;
+    std::vector<bool> regs;
     unsigned dollarLabel;
     int      clobbersMemory;
-    AsmCode() {
+    AsmCode(int n_regs) {
 	insnTemplate = NULL;
 	insnTemplateLen = 0;
-	moreRegs = 0;
+	regs.resize(n_regs, false);
 	dollarLabel = 0;
 	clobbersMemory = 0;
     }
@@ -77,7 +77,6 @@
     asmalign = 0;
     refparam = 0;
     naked = 0;
-    regs = 0;
 
     isBranchToLabel = NULL;
 }
@@ -89,7 +88,6 @@
     a_s->asmcode = asmcode;
     a_s->refparam = refparam;
     a_s->naked = naked;
-    a_s->regs = a_s->regs;
     return a_s;
 }
 
@@ -130,15 +128,22 @@
     return FALSE;
 }
 
+struct AsmParserCommon
+{
+    virtual void run(Scope* sc, AsmStatement* asmst) = 0;
+    virtual std::string getRegName(int i) = 0;
+};
+AsmParserCommon* asmparser = NULL;
 
-#include "d-asm-i386.h"
+#include "asm-x86-32.h"
+#include "asm-x86-64.h"
 
 bool d_have_inline_asm() { return true; }
 
 Statement *AsmStatement::semantic(Scope *sc)
 {
     bool err = false;
-    if (global.params.cpu != ARCHx86)
+    if ((global.params.cpu != ARCHx86) && (global.params.cpu != ARCHx86_64))
     {
         error("inline asm is not supported for the \"%s\" architecture", global.params.llvmArch);
         err = true;
@@ -160,8 +165,14 @@
     if (! tokens)
 	return this;
     
-    AsmProcessor ap(sc, this);
-    ap.run();
+    if (!asmparser)
+        if (global.params.cpu == ARCHx86)
+            asmparser = new AsmParserx8632::AsmParser;
+        else if (global.params.cpu == ARCHx86_64)
+            asmparser = new AsmParserx8664::AsmParser;
+
+    asmparser->run(sc, this);
+
     return this;
 }
 
@@ -251,7 +262,7 @@
 /*	    if (arg->expr->op == TOKvar)
 		arg_val = ((VarExp *) arg->expr)->var->toSymbol()->Stree;
 	    else
-		assert(0);*/
+		assert(0);
 	    if ( getFrameRelativeValue(arg_val, & var_frame_offset) ) {
 //		arg_val = irs->integerConstant(var_frame_offset);
 		cns = i_cns;
@@ -261,7 +272,7 @@
 	    }
 	    if (arg->mode != Mode_Input)
 		clobbers_mem = true;
-	    break;
+	    break;*/
 	case Arg_LocalSize:
 // FIXME
 std::cout << "asm fixme Arg_LocalSize" << std::endl;
@@ -294,16 +305,11 @@
     
 // FIXME
 //    if (! irs->func->naked) {
-	for (int i = 0; i < 32; i++) {
-	    if (regs & (1 << i)) {
+        assert(asmparser);
+	for (int i = 0; i < code->regs.size(); i++) {
+	    if (code->regs[i]) {
 		//clobbers.cons(NULL_TREE, regInfo[i].gccName);
-		clobbers.push_back(regInfo[i].gccName);
-	    }
-	}
-	for (int i = 0; i < 32; i++) {
-	    if (code->moreRegs & (1 << (i-32))) {
-		//clobbers.cons(NULL_TREE, regInfo[i].gccName);
-		clobbers.push_back(regInfo[i].gccName);
+		clobbers.push_back(asmparser->getRegName(i));
 	    }
 	}
 	if (clobbers_mem)