# HG changeset patch # User lindquist # Date 1212867098 -7200 # Node ID cac3d27ae481c26f66a694e0f9ce3cc14b30af9e # Parent 52d1e9d27dc62c6b176f2bacb96923256d6ae17f [svn r245] initial support for labels in inline asm, broken :/ diff -r 52d1e9d27dc6 -r cac3d27ae481 gen/asmstmt.cpp --- 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 const& output_values, std::deque const& input_values, std::string constraints) +d_build_asm_stmt(std::string const& code, + std::deque const& output_values, + std::deque const& input_values, + std::string const& constraints) { std::vector 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 input_values; + std::deque input_values; std::deque input_constraints; - std::deque output_values; + std::deque output_values; std::deque output_constraints; std::deque 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; igetRVal(); - callargs.push_back(val); + callargs.push_back(output_values[i]); } cn = input_values.size(); for (size_t i=0; igetRVal(); - 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); -*/ } diff -r 52d1e9d27dc6 -r cac3d27ae481 gen/d-asm-i386.h --- 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 diff -r 52d1e9d27dc6 -r cac3d27ae481 llvmdc.kdevelop.filelist --- 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 diff -r 52d1e9d27dc6 -r cac3d27ae481 tangotests/asm4.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;