Mercurial > projects > ldc
comparison gen/d-asm-i386.h @ 232:092468448d25 trunk
[svn r248] Fixed: labels in inline asm block now work for the normal case.
Fixed: inline asm blocks are now emitted as a single asm entity.
author | lindquist |
---|---|
date | Sun, 08 Jun 2008 06:15:51 +0200 |
parents | 61aa721a6b7f |
children | 9760f54af0b7 |
comparison
equal
deleted
inserted
replaced
231:61aa721a6b7f | 232:092468448d25 |
---|---|
1406 return false; | 1406 return false; |
1407 } | 1407 } |
1408 | 1408 |
1409 void addOperand(const char * fmt, AsmArgType type, Expression * e, AsmCode * asmcode, AsmArgMode mode = Mode_Input) { | 1409 void addOperand(const char * fmt, AsmArgType type, Expression * e, AsmCode * asmcode, AsmArgMode mode = Mode_Input) { |
1410 insnTemplate->writestring((char*) fmt); | 1410 insnTemplate->writestring((char*) fmt); |
1411 insnTemplate->printf("%d", asmcode->args.dim); | 1411 insnTemplate->printf("<<<%s%d>>>", (mode==Mode_Input)?"in":"out", asmcode->args.dim); |
1412 asmcode->args.push( new AsmArg(type, e, mode) ); | 1412 asmcode->args.push( new AsmArg(type, e, mode) ); |
1413 } | 1413 } |
1414 void addOperand2(const char * fmtpre, const char * fmtpost, AsmArgType type, Expression * e, AsmCode * asmcode, AsmArgMode mode = Mode_Input) { | 1414 void addOperand2(const char * fmtpre, const char * fmtpost, AsmArgType type, Expression * e, AsmCode * asmcode, AsmArgMode mode = Mode_Input) { |
1415 insnTemplate->writestring((char*) fmtpre); | 1415 insnTemplate->writestring((char*) fmtpre); |
1416 insnTemplate->printf("%d", asmcode->args.dim); | 1416 insnTemplate->printf("<<<%s%d>>>", (mode==Mode_Input)?"in":"out", asmcode->args.dim); |
1417 insnTemplate->writestring((char*) fmtpost); | 1417 insnTemplate->writestring((char*) fmtpost); |
1418 asmcode->args.push( new AsmArg(type, e, mode) ); | 1418 asmcode->args.push( new AsmArg(type, e, mode) ); |
1419 } | 1419 } |
1420 | 1420 |
1421 void addLabel(unsigned n) { | 1421 void addLabel(unsigned n) { |
1422 // No longer taking the address of the actual label -- doesn't seem like it would help. | 1422 // No longer taking the address of the actual label -- doesn't seem like it would help. |
1423 char buf[64]; | 1423 char buf[64]; |
1424 | 1424 |
1425 d_format_priv_asm_label(buf, n); | 1425 d_format_priv_asm_label(buf, n); |
1426 insnTemplate->writestring(buf); | 1426 insnTemplate->writestring(buf); |
1427 } | |
1428 | |
1429 void addLabel(char* id) { | |
1430 insnTemplate->writestring(".LDASM"); | |
1431 insnTemplate->writestring(id); | |
1427 } | 1432 } |
1428 | 1433 |
1429 /* Determines whether the operand is a register, memory reference | 1434 /* Determines whether the operand is a register, memory reference |
1430 or immediate. Immediate addresses are currently classified as | 1435 or immediate. Immediate addresses are currently classified as |
1431 memory. This function is called before the exact instructions | 1436 memory. This function is called before the exact instructions |
1885 operand->baseReg = Reg_Invalid; | 1890 operand->baseReg = Reg_Invalid; |
1886 | 1891 |
1887 addOperand(fmt, Arg_Memory, e, asmcode, mode); | 1892 addOperand(fmt, Arg_Memory, e, asmcode, mode); |
1888 | 1893 |
1889 } else { | 1894 } else { |
1890 addOperand("$a", Arg_FrameRelative, e, asmcode); | 1895 addOperand2("${",":a}", Arg_FrameRelative, e, asmcode); |
1891 } | 1896 } |
1892 if (opInfo->operands[i] & Opr_Dest) | 1897 if (opInfo->operands[i] & Opr_Dest) |
1893 asmcode->clobbersMemory = 1; | 1898 asmcode->clobbersMemory = 1; |
1894 } else { | 1899 } else { |
1895 // Plain memory reference to variable | 1900 // Plain memory reference to variable |
1903 if (isDollar(e)) { | 1908 if (isDollar(e)) { |
1904 unsigned lbl_num = ++d_priv_asm_label_serial; | 1909 unsigned lbl_num = ++d_priv_asm_label_serial; |
1905 addLabel(lbl_num); | 1910 addLabel(lbl_num); |
1906 asmcode->dollarLabel = lbl_num; // could make the dollar label part of the same asm.. | 1911 asmcode->dollarLabel = lbl_num; // could make the dollar label part of the same asm.. |
1907 } else if (e->op == TOKdsymbol) { | 1912 } else if (e->op == TOKdsymbol) { |
1908 // LabelDsymbol * lbl = (LabelDsymbol *) ((DsymbolExp *) e)->s; | 1913 LabelDsymbol * lbl = (LabelDsymbol *) ((DsymbolExp *) e)->s; |
1909 // if (! lbl->asmLabelNum) | 1914 if (! lbl->asmLabelNum) |
1910 // lbl->asmLabelNum = ++d_priv_asm_label_serial; | 1915 lbl->asmLabelNum = ++d_priv_asm_label_serial; |
1911 // | 1916 |
1912 // use_star = false; | 1917 use_star = false; |
1913 // addLabel(lbl->asmLabelNum); | 1918 addLabel(lbl->ident->toChars()); |
1914 use_star = false; | |
1915 addOperand("$", Arg_Pointer, e, asmcode); | |
1916 } else if ((decl && decl->isCodeseg())) { // if function or label | 1919 } else if ((decl && decl->isCodeseg())) { // if function or label |
1917 use_star = false; | 1920 use_star = false; |
1918 addOperand2("${", ":c}", Arg_Pointer, e, asmcode); | 1921 addOperand2("${", ":c}", Arg_Pointer, e, asmcode); |
1919 } else { | 1922 } else { |
1920 if (use_star) { | 1923 if (use_star) { |
1921 insnTemplate->writebyte('*'); | 1924 insnTemplate->writebyte('*'); |
1922 use_star = false; | 1925 use_star = false; |
1923 } | 1926 } |
1927 Type* tt = e->type->pointerTo(); | |
1924 e = new AddrExp(0, e); | 1928 e = new AddrExp(0, e); |
1925 assert(decl); | 1929 e->type = tt; |
1926 e->type = decl->type->pointerTo(); | |
1927 | 1930 |
1928 addOperand(fmt, Arg_Memory, e, asmcode, mode); | 1931 addOperand(fmt, Arg_Memory, e, asmcode, mode); |
1929 } | 1932 } |
1930 } | 1933 } |
1931 } | 1934 } |
1932 if (use_star) | 1935 if (use_star) |
1933 insnTemplate->writebyte('*'); | 1936 insnTemplate->writebyte('*'); |
1934 if (operand->constDisplacement) { | 1937 if (operand->constDisplacement) { |
1935 if (operand->symbolDisplacement.dim) | 1938 if (operand->symbolDisplacement.dim) |
1936 insnTemplate->writebyte('+'); | 1939 insnTemplate->writebyte('+'); |
1937 addOperand("$a", Arg_Integer, newIntExp(operand->constDisplacement), asmcode); | 1940 addOperand2("${",":a}", Arg_Integer, newIntExp(operand->constDisplacement), asmcode); |
1938 if (opInfo->operands[i] & Opr_Dest) | 1941 if (opInfo->operands[i] & Opr_Dest) |
1939 asmcode->clobbersMemory = 1; | 1942 asmcode->clobbersMemory = 1; |
1940 } | 1943 } |
1941 if (operand->baseReg != Reg_Invalid || operand->indexReg != Reg_Invalid) { | 1944 if (operand->baseReg != Reg_Invalid || operand->indexReg != Reg_Invalid) { |
1942 insnTemplate->writebyte('('); | 1945 insnTemplate->writebyte('('); |