changeset 229:cac3d27ae481 trunk

[svn r245] initial support for labels in inline asm, broken :/
author lindquist
date Sat, 07 Jun 2008 21:31:38 +0200
parents 52d1e9d27dc6
children 79d8f6b3fbaf
files gen/asmstmt.cpp gen/d-asm-i386.h llvmdc.kdevelop.filelist tangotests/asm4.d
diffstat 4 files changed, 86 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/gen/asmstmt.cpp	Sat Jun 07 19:20:15 2008 +0200
+++ b/gen/asmstmt.cpp	Sat Jun 07 21:31:38 2008 +0200
@@ -68,7 +68,10 @@
 };
 
 llvm::InlineAsm*
-d_build_asm_stmt(std::string code, std::deque<DValue*> const& output_values, std::deque<DValue*> const& input_values, std::string constraints)
+d_build_asm_stmt(std::string const& code,
+                 std::deque<LLValue*> const& output_values,
+                 std::deque<LLValue*> const& input_values,
+                 std::string const& constraints)
 {
     std::vector<const LLType*> params;
 
@@ -77,7 +80,7 @@
     if (!output_values.empty())
     {
         assert(output_values.size() == 1);
-        const LLType* llty = DtoType(output_values[0]->getType());
+        const LLType* llty = output_values[0]->getType();
         std::cout << "out: " << *llty << '\n';
         params.push_back(llty);
     }
@@ -86,7 +89,7 @@
     if (!input_values.empty())
     {
         assert(input_values.size() == 1);
-        const LLType* llty = DtoType(input_values[0]->getType());
+        const LLType* llty = input_values[0]->getType();
         std::cout << "in: " << *llty << '\n';
         params.push_back(llty);
     }
@@ -256,15 +259,16 @@
 
     static std::string i_cns = "i";
     static std::string p_cns = "m";
+    static std::string l_cns = "X";
     static std::string m_cns = "*m";
     static std::string mw_cns = "=*m";
     static std::string mrw_cns = "+*m";
     static std::string memory_name = "memory";
 
     AsmCode * code = (AsmCode *) asmcode;
-    std::deque<DValue*> input_values;
+    std::deque<LLValue*> input_values;
     std::deque<std::string> input_constraints;
-    std::deque<DValue*> output_values;
+    std::deque<LLValue*> output_values;
     std::deque<std::string> output_constraints;
     std::deque<std::string> clobbers;
 
@@ -282,22 +286,37 @@
 	AsmArg * arg = (AsmArg *) code->args.data[i];
 	
 	bool is_input = true;
-	DValue* arg_val = 0;
+	LLValue* arg_val = 0;
 	std::string cns;
 
 std::cout << std::endl;
 
 	switch (arg->type) {
 	case Arg_Integer:
-	    arg_val = arg->expr->toElem(irs);
+	    arg_val = arg->expr->toElem(irs)->getRVal();
 	do_integer:
 	    cns = i_cns;
 	    break;
 	case Arg_Pointer:
 // FIXME
 std::cout << "asm fixme Arg_Pointer" << std::endl;
-        arg_val = arg->expr->toElem(irs);
-        arg_val = new DVarValue(arg_val->getType()->pointerTo(), arg_val->getRVal(), true);
+        if (arg->expr->op == TOKdsymbol)
+        {
+            DsymbolExp* dse = (DsymbolExp*)arg->expr;
+            LabelDsymbol* lbl = dse->s->isLabel();
+            assert(lbl);
+            arg_val = lbl->statement->llvmBB;
+            if (!arg_val)
+            {
+                arg_val = lbl->statement->llvmBB = llvm::BasicBlock::Create("label", irs->topfunc());
+            }
+            cns = l_cns;
+        }
+        else
+        {
+            arg_val = arg->expr->toElem(irs)->getRVal();
+            cns = p_cns;
+        }
         /*if (arg->expr->op == TOKvar)
         arg_val = arg->expr->toElem(irs);
         else if (arg->expr->op == TOKdsymbol)
@@ -305,15 +324,15 @@
         else
         assert(0);*/
 
-	    cns = p_cns;
 	    break;
 	case Arg_Memory:
 // FIXME
 std::cout << "asm fixme Arg_Memory" << std::endl;
-        if (arg->expr->op == TOKvar)
-        arg_val = arg->expr->toElem(irs);
-        else
-        arg_val = arg->expr->toElem(irs);
+        arg_val = arg->expr->toElem(irs)->getRVal();
+//         if (arg->expr->op == TOKvar)
+//         arg_val = arg->expr->toElem(irs);
+//         else
+//         arg_val = arg->expr->toElem(irs);
 
 	    switch (arg->mode) {
 	    case Mode_Input:  cns = m_cns; break;
@@ -325,6 +344,7 @@
 	case Arg_FrameRelative:
 // FIXME
 std::cout << "asm fixme Arg_FrameRelative" << std::endl;
+assert(0);
 /*	    if (arg->expr->op == TOKvar)
 		arg_val = ((VarExp *) arg->expr)->var->toSymbol()->Stree;
 	    else
@@ -342,6 +362,7 @@
 	case Arg_LocalSize:
 // FIXME
 std::cout << "asm fixme Arg_LocalSize" << std::endl;
+assert(0);
 /*	    var_frame_offset = cfun->x_frame_offset;
 	    if (var_frame_offset < 0)
 		var_frame_offset = - var_frame_offset;
@@ -460,26 +481,14 @@
     size_t cn = output_values.size();
     for (size_t i=0; i<cn; ++i)
     {
-        LLValue* val = output_values[i]->getRVal();
-        callargs.push_back(val);
+        callargs.push_back(output_values[i]);
     }
 
     cn = input_values.size();
     for (size_t i=0; i<cn; ++i)
     {
-        // FIXME: these should not be allowed to intermix with asm calls. they should somehow
-        // be outputted before any asm from a block, or the asm's should be moved after ...
-        LLValue* val = input_values[i]->getRVal();
-        callargs.push_back(val);
+        callargs.push_back(input_values[i]);
     }
 
     llvm::CallInst* call = irs->ir->CreateCall(t, callargs.begin(), callargs.end(), "");
-
-/*
-// FIXME
-    //ASM_VOLATILE_P( t ) = 1;
-    //irs->addExp( t );
-    if (code->dollarLabel)
-    d_expand_priv_asm_label(irs, code->dollarLabel);
-*/
 }
--- a/gen/d-asm-i386.h	Sat Jun 07 19:20:15 2008 +0200
+++ b/gen/d-asm-i386.h	Sat Jun 07 21:31:38 2008 +0200
@@ -1413,11 +1413,11 @@
     }
 
     void addLabel(unsigned n) {
-	// No longer taking the address of the actual label -- doesn't seem like it would help.
-	char buf[64];
-	
-	d_format_priv_asm_label(buf, n);
-	insnTemplate->writestring(buf);
+    // No longer taking the address of the actual label -- doesn't seem like it would help.
+    char buf[64];
+    
+    d_format_priv_asm_label(buf, n);
+    insnTemplate->writestring(buf);
     }
 
     /* Determines whether the operand is a register, memory reference
@@ -1899,12 +1899,14 @@
 			    addLabel(lbl_num);
 			    asmcode->dollarLabel = lbl_num; // could make the dollar label part of the same asm..
 			} else if (e->op == TOKdsymbol) {
-			    LabelDsymbol * lbl = (LabelDsymbol *) ((DsymbolExp *) e)->s;
-			    if (! lbl->asmLabelNum)
-				lbl->asmLabelNum = ++d_priv_asm_label_serial;
-			    
-			    use_star = false;
-			    addLabel(lbl->asmLabelNum);
+// 			    LabelDsymbol * lbl = (LabelDsymbol *) ((DsymbolExp *) e)->s;
+// 			    if (! lbl->asmLabelNum)
+// 				lbl->asmLabelNum = ++d_priv_asm_label_serial;
+// 			    
+// 			    use_star = false;
+// 			    addLabel(lbl->asmLabelNum);
+                use_star = false;
+                addOperand("$", Arg_Pointer, e, asmcode);
 			} else if ((decl && decl->isCodeseg())) { // if function or label
 			    use_star = false;
 			    addOperand("*$", Arg_Pointer, e, asmcode);
@@ -2389,7 +2391,10 @@
 	case TOKfloat64v:
 	case TOKfloat80v:
 	    // %% need different types?
-	    e = new RealExp(stmt->loc, token->float80value, Type::tfloat80);
+        if (global.params.useFP80)
+	       e = new RealExp(stmt->loc, token->float80value, Type::tfloat80);
+        else
+            e = new RealExp(stmt->loc, token->float80value, Type::tfloat64);
 	    nextToken();
 	    break;
 	case TOKidentifier:
@@ -2630,7 +2635,7 @@
 
 // FIXME
     #define HOST_WIDE_INT long
-bool getFrameRelativeValue(DValue* decl, HOST_WIDE_INT * result)
+bool getFrameRelativeValue(LLValue* decl, HOST_WIDE_INT * result)
 {
 // FIXME
 //     // Using this instead of DECL_RTL for struct args seems like a
--- a/llvmdc.kdevelop.filelist	Sat Jun 07 19:20:15 2008 +0200
+++ b/llvmdc.kdevelop.filelist	Sat Jun 07 21:31:38 2008 +0200
@@ -753,6 +753,7 @@
 tangotests/asm1.d
 tangotests/asm2.d
 tangotests/asm3.d
+tangotests/asm4.d
 tangotests/b.d
 tangotests/byval1.d
 tangotests/c.d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tangotests/asm4.d	Sat Jun 07 21:31:38 2008 +0200
@@ -0,0 +1,30 @@
+module tangotests.asm4;
+
+extern(C) int printf(char*,...);
+
+void main()
+{
+    char* fmt = "yay!\n";
+    asm
+    {
+        jmp L2;
+    L1:;
+        jmp L3;
+    L2:;
+        jmp L1;
+    L3:;
+        push fmt;
+        call printf;
+        pop EAX;
+    }
+    if (x)
+    {
+        printf("foobar\n");
+    }
+    else
+    {
+        printf("baz\n");
+    }
+}
+
+extern(C) extern int x;