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('(');