comparison 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
comparison
equal deleted inserted replaced
755:61c7a96f28c3 756:a58784e0f035
55 55
56 struct AsmCode { 56 struct AsmCode {
57 char * insnTemplate; 57 char * insnTemplate;
58 unsigned insnTemplateLen; 58 unsigned insnTemplateLen;
59 Array args; // of AsmArg 59 Array args; // of AsmArg
60 unsigned moreRegs; 60 std::vector<bool> regs;
61 unsigned dollarLabel; 61 unsigned dollarLabel;
62 int clobbersMemory; 62 int clobbersMemory;
63 AsmCode() { 63 AsmCode(int n_regs) {
64 insnTemplate = NULL; 64 insnTemplate = NULL;
65 insnTemplateLen = 0; 65 insnTemplateLen = 0;
66 moreRegs = 0; 66 regs.resize(n_regs, false);
67 dollarLabel = 0; 67 dollarLabel = 0;
68 clobbersMemory = 0; 68 clobbersMemory = 0;
69 } 69 }
70 }; 70 };
71 71
75 this->tokens = tokens; // Do I need to copy these? 75 this->tokens = tokens; // Do I need to copy these?
76 asmcode = 0; 76 asmcode = 0;
77 asmalign = 0; 77 asmalign = 0;
78 refparam = 0; 78 refparam = 0;
79 naked = 0; 79 naked = 0;
80 regs = 0;
81 80
82 isBranchToLabel = NULL; 81 isBranchToLabel = NULL;
83 } 82 }
84 83
85 Statement *AsmStatement::syntaxCopy() 84 Statement *AsmStatement::syntaxCopy()
87 // copy tokens? copy 'code'? 86 // copy tokens? copy 'code'?
88 AsmStatement * a_s = new AsmStatement(loc,tokens); 87 AsmStatement * a_s = new AsmStatement(loc,tokens);
89 a_s->asmcode = asmcode; 88 a_s->asmcode = asmcode;
90 a_s->refparam = refparam; 89 a_s->refparam = refparam;
91 a_s->naked = naked; 90 a_s->naked = naked;
92 a_s->regs = a_s->regs;
93 return a_s; 91 return a_s;
94 } 92 }
95 93
96 void AsmStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 94 void AsmStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
97 { 95 {
128 int AsmStatement::comeFrom() 126 int AsmStatement::comeFrom()
129 { 127 {
130 return FALSE; 128 return FALSE;
131 } 129 }
132 130
133 131 struct AsmParserCommon
134 #include "d-asm-i386.h" 132 {
133 virtual void run(Scope* sc, AsmStatement* asmst) = 0;
134 virtual std::string getRegName(int i) = 0;
135 };
136 AsmParserCommon* asmparser = NULL;
137
138 #include "asm-x86-32.h"
139 #include "asm-x86-64.h"
135 140
136 bool d_have_inline_asm() { return true; } 141 bool d_have_inline_asm() { return true; }
137 142
138 Statement *AsmStatement::semantic(Scope *sc) 143 Statement *AsmStatement::semantic(Scope *sc)
139 { 144 {
140 bool err = false; 145 bool err = false;
141 if (global.params.cpu != ARCHx86) 146 if ((global.params.cpu != ARCHx86) && (global.params.cpu != ARCHx86_64))
142 { 147 {
143 error("inline asm is not supported for the \"%s\" architecture", global.params.llvmArch); 148 error("inline asm is not supported for the \"%s\" architecture", global.params.llvmArch);
144 err = true; 149 err = true;
145 } 150 }
146 if (!global.params.useInlineAsm) 151 if (!global.params.useInlineAsm)
158 163
159 // empty statement -- still do the above things because they might be expected? 164 // empty statement -- still do the above things because they might be expected?
160 if (! tokens) 165 if (! tokens)
161 return this; 166 return this;
162 167
163 AsmProcessor ap(sc, this); 168 if (!asmparser)
164 ap.run(); 169 if (global.params.cpu == ARCHx86)
170 asmparser = new AsmParserx8632::AsmParser;
171 else if (global.params.cpu == ARCHx86_64)
172 asmparser = new AsmParserx8664::AsmParser;
173
174 asmparser->run(sc, this);
175
165 return this; 176 return this;
166 } 177 }
167 178
168 int AsmStatement::blockExit() 179 int AsmStatement::blockExit()
169 { 180 {
249 std::cout << "asm fixme Arg_FrameRelative" << std::endl; 260 std::cout << "asm fixme Arg_FrameRelative" << std::endl;
250 assert(0); 261 assert(0);
251 /* if (arg->expr->op == TOKvar) 262 /* if (arg->expr->op == TOKvar)
252 arg_val = ((VarExp *) arg->expr)->var->toSymbol()->Stree; 263 arg_val = ((VarExp *) arg->expr)->var->toSymbol()->Stree;
253 else 264 else
254 assert(0);*/ 265 assert(0);
255 if ( getFrameRelativeValue(arg_val, & var_frame_offset) ) { 266 if ( getFrameRelativeValue(arg_val, & var_frame_offset) ) {
256 // arg_val = irs->integerConstant(var_frame_offset); 267 // arg_val = irs->integerConstant(var_frame_offset);
257 cns = i_cns; 268 cns = i_cns;
258 } else { 269 } else {
259 this->error("%s", "argument not frame relative"); 270 this->error("%s", "argument not frame relative");
260 return; 271 return;
261 } 272 }
262 if (arg->mode != Mode_Input) 273 if (arg->mode != Mode_Input)
263 clobbers_mem = true; 274 clobbers_mem = true;
264 break; 275 break;*/
265 case Arg_LocalSize: 276 case Arg_LocalSize:
266 // FIXME 277 // FIXME
267 std::cout << "asm fixme Arg_LocalSize" << std::endl; 278 std::cout << "asm fixme Arg_LocalSize" << std::endl;
268 assert(0); 279 assert(0);
269 /* var_frame_offset = cfun->x_frame_offset; 280 /* var_frame_offset = cfun->x_frame_offset;
292 // those registers. This changes the stack from what a naked function 303 // those registers. This changes the stack from what a naked function
293 // expects. 304 // expects.
294 305
295 // FIXME 306 // FIXME
296 // if (! irs->func->naked) { 307 // if (! irs->func->naked) {
297 for (int i = 0; i < 32; i++) { 308 assert(asmparser);
298 if (regs & (1 << i)) { 309 for (int i = 0; i < code->regs.size(); i++) {
310 if (code->regs[i]) {
299 //clobbers.cons(NULL_TREE, regInfo[i].gccName); 311 //clobbers.cons(NULL_TREE, regInfo[i].gccName);
300 clobbers.push_back(regInfo[i].gccName); 312 clobbers.push_back(asmparser->getRegName(i));
301 }
302 }
303 for (int i = 0; i < 32; i++) {
304 if (code->moreRegs & (1 << (i-32))) {
305 //clobbers.cons(NULL_TREE, regInfo[i].gccName);
306 clobbers.push_back(regInfo[i].gccName);
307 } 313 }
308 } 314 }
309 if (clobbers_mem) 315 if (clobbers_mem)
310 clobbers.push_back(memory_name); 316 clobbers.push_back(memory_name);
311 //clobbers.cons(NULL_TREE, memory_name); 317 //clobbers.cons(NULL_TREE, memory_name);