Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(235)

Side by Side Diff: src/IceTargetLoweringX8664.cpp

Issue 1273153002: Subzero. Native 64-bit int arithmetic on x86-64. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Removes the x8664-specific xtest target. Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 //===- subzero/src/IceTargetLoweringX8664.cpp - x86-64 lowering -----------===// 1 //===- subzero/src/IceTargetLoweringX8664.cpp - x86-64 lowering -----------===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 /// 9 ///
10 /// \file 10 /// \file
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 TargetX8664::Traits::RegisterSet::Reg_r8d, 116 TargetX8664::Traits::RegisterSet::Reg_r8d,
117 TargetX8664::Traits::RegisterSet::Reg_r9d, 117 TargetX8664::Traits::RegisterSet::Reg_r9d,
118 }; 118 };
119 static_assert(llvm::array_lengthof(GprForArgNum) == 119 static_assert(llvm::array_lengthof(GprForArgNum) ==
120 TargetX8664::TargetX8664::Traits::X86_MAX_GPR_ARGS, 120 TargetX8664::TargetX8664::Traits::X86_MAX_GPR_ARGS,
121 "Mismatch between MAX_GPR_ARGS and GprForArgNum."); 121 "Mismatch between MAX_GPR_ARGS and GprForArgNum.");
122 return GprForArgNum[ArgNum]; 122 return GprForArgNum[ArgNum];
123 } 123 }
124 124
125 // constexprMax returns a (constexpr) max(S0, S1), and it is used for defining 125 // constexprMax returns a (constexpr) max(S0, S1), and it is used for defining
126 // OperandList in lowerCall. std::max() was supposed to work, but it doesn't. 126 // OperandList in lowerCall. std::max() is supposed to work, but it doesn't.
127 constexpr SizeT constexprMax(SizeT S0, SizeT S1) { return S0 < S1 ? S1 : S0; } 127 constexpr SizeT constexprMax(SizeT S0, SizeT S1) { return S0 < S1 ? S1 : S0; }
128 128
129 } // end of anonymous namespace 129 } // end of anonymous namespace
130 130
131 void TargetX8664::lowerCall(const InstCall *Instr) { 131 void TargetX8664::lowerCall(const InstCall *Instr) {
132 // x86-64 calling convention: 132 // x86-64 calling convention:
133 // 133 //
134 // * At the point before the call, the stack must be aligned to 16 134 // * At the point before the call, the stack must be aligned to 16
135 // bytes. 135 // bytes.
136 // 136 //
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 for (SizeT i = 0, NumGprArgs = GprArgs.size(); i < NumGprArgs; ++i) { 232 for (SizeT i = 0, NumGprArgs = GprArgs.size(); i < NumGprArgs; ++i) {
233 Variable *Reg = legalizeToReg(GprArgs[i], getRegisterForGprArgNum(i)); 233 Variable *Reg = legalizeToReg(GprArgs[i], getRegisterForGprArgNum(i));
234 Context.insert(InstFakeUse::create(Func, Reg)); 234 Context.insert(InstFakeUse::create(Func, Reg));
235 } 235 }
236 236
237 // Generate the call instruction. Assign its result to a temporary 237 // Generate the call instruction. Assign its result to a temporary
238 // with high register allocation weight. 238 // with high register allocation weight.
239 Variable *Dest = Instr->getDest(); 239 Variable *Dest = Instr->getDest();
240 // ReturnReg doubles as ReturnRegLo as necessary. 240 // ReturnReg doubles as ReturnRegLo as necessary.
241 Variable *ReturnReg = nullptr; 241 Variable *ReturnReg = nullptr;
242 Variable *ReturnRegHi = nullptr;
243 if (Dest) { 242 if (Dest) {
244 switch (Dest->getType()) { 243 switch (Dest->getType()) {
245 case IceType_NUM: 244 case IceType_NUM:
246 case IceType_void: 245 case IceType_void:
247 llvm::report_fatal_error("Invalid Call dest type"); 246 llvm::report_fatal_error("Invalid Call dest type");
248 break; 247 break;
249 case IceType_i1: 248 case IceType_i1:
250 case IceType_i8: 249 case IceType_i8:
251 case IceType_i16: 250 case IceType_i16:
252 case IceType_i32: 251 case IceType_i32:
252 case IceType_i64:
253 ReturnReg = makeReg(Dest->getType(), Traits::RegisterSet::Reg_eax); 253 ReturnReg = makeReg(Dest->getType(), Traits::RegisterSet::Reg_eax);
254 break; 254 break;
255 case IceType_i64:
256 // TODO(jpp): return i64 in a GPR.
257 ReturnReg = makeReg(IceType_i32, Traits::RegisterSet::Reg_eax);
258 ReturnRegHi = makeReg(IceType_i32, Traits::RegisterSet::Reg_edx);
259 break;
260 case IceType_f32: 255 case IceType_f32:
261 case IceType_f64: 256 case IceType_f64:
262 case IceType_v4i1: 257 case IceType_v4i1:
263 case IceType_v8i1: 258 case IceType_v8i1:
264 case IceType_v16i1: 259 case IceType_v16i1:
265 case IceType_v16i8: 260 case IceType_v16i8:
266 case IceType_v8i16: 261 case IceType_v8i16:
267 case IceType_v4i32: 262 case IceType_v4i32:
268 case IceType_v4f32: 263 case IceType_v4f32:
269 ReturnReg = makeReg(Dest->getType(), Traits::RegisterSet::Reg_xmm0); 264 ReturnReg = makeReg(Dest->getType(), Traits::RegisterSet::Reg_xmm0);
270 break; 265 break;
271 } 266 }
272 } 267 }
273 268
274 Operand *CallTarget = legalize(Instr->getCallTarget()); 269 Operand *CallTarget = legalize(Instr->getCallTarget(), Legal_Reg | Legal_Imm);
275 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing(); 270 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing();
276 if (NeedSandboxing) { 271 if (NeedSandboxing) {
277 if (llvm::isa<Constant>(CallTarget)) { 272 llvm_unreachable("X86-64 Sandboxing codegen not implemented.");
278 _bundle_lock(InstBundleLock::Opt_AlignToEnd);
279 } else {
280 Variable *CallTargetVar = nullptr;
281 _mov(CallTargetVar, CallTarget);
282 _bundle_lock(InstBundleLock::Opt_AlignToEnd);
283 const SizeT BundleSize =
284 1 << Func->getAssembler<>()->getBundleAlignLog2Bytes();
285 _and(CallTargetVar, Ctx->getConstantInt32(~(BundleSize - 1)));
286 CallTarget = CallTargetVar;
287 }
288 } 273 }
289 Inst *NewCall = Traits::Insts::Call::create(Func, ReturnReg, CallTarget); 274 Inst *NewCall = Traits::Insts::Call::create(Func, ReturnReg, CallTarget);
290 Context.insert(NewCall); 275 Context.insert(NewCall);
291 if (NeedSandboxing) 276 if (NeedSandboxing) {
292 _bundle_unlock(); 277 llvm_unreachable("X86-64 Sandboxing codegen not implemented.");
293 if (ReturnRegHi) 278 }
294 Context.insert(InstFakeDef::create(Func, ReturnRegHi));
295 279
296 // Add the appropriate offset to esp. The call instruction takes care 280 // Add the appropriate offset to esp. The call instruction takes care
297 // of resetting the stack offset during emission. 281 // of resetting the stack offset during emission.
298 if (ParameterAreaSizeBytes) { 282 if (ParameterAreaSizeBytes) {
299 Variable *Esp = 283 Variable *Esp =
300 Func->getTarget()->getPhysicalRegister(Traits::RegisterSet::Reg_esp); 284 Func->getTarget()->getPhysicalRegister(Traits::RegisterSet::Reg_esp);
301 _add(Esp, Ctx->getConstantInt32(ParameterAreaSizeBytes)); 285 _add(Esp, Ctx->getConstantInt32(ParameterAreaSizeBytes));
302 } 286 }
303 287
304 // Insert a register-kill pseudo instruction. 288 // Insert a register-kill pseudo instruction.
305 Context.insert(InstFakeKill::create(Func, NewCall)); 289 Context.insert(InstFakeKill::create(Func, NewCall));
306 290
307 // Generate a FakeUse to keep the call live if necessary. 291 // Generate a FakeUse to keep the call live if necessary.
308 if (Instr->hasSideEffects() && ReturnReg) { 292 if (Instr->hasSideEffects() && ReturnReg) {
309 Inst *FakeUse = InstFakeUse::create(Func, ReturnReg); 293 Inst *FakeUse = InstFakeUse::create(Func, ReturnReg);
310 Context.insert(FakeUse); 294 Context.insert(FakeUse);
311 } 295 }
312 296
313 if (!Dest) 297 if (!Dest)
314 return; 298 return;
315 299
316 assert(ReturnReg && "x86-64 always returns value on registers."); 300 assert(ReturnReg && "x86-64 always returns value on registers.");
317 301
318 // Assign the result of the call to Dest. 302 if (isVectorType(Dest->getType())) {
319 if (ReturnRegHi) {
320 assert(Dest->getType() == IceType_i64);
321 split64(Dest);
322 Variable *DestLo = Dest->getLo();
323 Variable *DestHi = Dest->getHi();
324 _mov(DestLo, ReturnReg);
325 _mov(DestHi, ReturnRegHi);
326 return;
327 }
328
329 assert(Dest->getType() == IceType_f32 || Dest->getType() == IceType_f64 ||
330 Dest->getType() == IceType_i32 || Dest->getType() == IceType_i16 ||
331 Dest->getType() == IceType_i8 || Dest->getType() == IceType_i1 ||
332 isVectorType(Dest->getType()));
333
334 if (isScalarFloatingType(Dest->getType()) || isVectorType(Dest->getType())) {
335 _movp(Dest, ReturnReg); 303 _movp(Dest, ReturnReg);
336 } else { 304 } else {
305 assert(isScalarFloatingType(Dest->getType()) ||
306 isScalarIntegerType(Dest->getType()));
337 _mov(Dest, ReturnReg); 307 _mov(Dest, ReturnReg);
338 } 308 }
339 } 309 }
340 310
341 void TargetX8664::lowerArguments() { 311 void TargetX8664::lowerArguments() {
342 VarList &Args = Func->getArgs(); 312 VarList &Args = Func->getArgs();
343 // The first eight vetcor typed arguments (as well as fp arguments) are passed 313 // The first eight vetcor typed arguments (as well as fp arguments) are passed
344 // in %xmm0 through %xmm7 regardless of their position in the argument list. 314 // in %xmm0 through %xmm7 regardless of their position in the argument list.
345 unsigned NumXmmArgs = 0; 315 unsigned NumXmmArgs = 0;
346 // The first six integer typed arguments are passed in %rdi, %rsi, %rdx, %rcx, 316 // The first six integer typed arguments are passed in %rdi, %rsi, %rdx, %rcx,
347 // %r8, and %r9 regardless of their position in the argument list. 317 // %r8, and %r9 regardless of their position in the argument list.
348 unsigned NumGprArgs = 0; 318 unsigned NumGprArgs = 0;
349 319
350 Context.init(Func->getEntryNode()); 320 Context.init(Func->getEntryNode());
351 Context.setInsertPoint(Context.getCur()); 321 Context.setInsertPoint(Context.getCur());
352 322
353 for (SizeT i = 0, End = Args.size(); 323 for (SizeT i = 0, End = Args.size();
354 i < End && (NumXmmArgs < Traits::X86_MAX_XMM_ARGS || 324 i < End && (NumXmmArgs < Traits::X86_MAX_XMM_ARGS ||
355 NumGprArgs < Traits::X86_MAX_XMM_ARGS); 325 NumGprArgs < Traits::X86_MAX_XMM_ARGS);
356 ++i) { 326 ++i) {
357 Variable *Arg = Args[i]; 327 Variable *Arg = Args[i];
358 Type Ty = Arg->getType(); 328 Type Ty = Arg->getType();
359 if ((isVectorType(Ty) || isScalarFloatingType(Ty)) && 329 Variable *RegisterArg = nullptr;
360 NumXmmArgs < Traits::X86_MAX_XMM_ARGS) { 330 int32_t RegNum = -1;
Jim Stichnoth 2015/08/10 16:08:05 I think you should be able to use Variable::NoRegi
John 2015/08/10 20:41:17 Done.
361 // Replace Arg in the argument list with the home register. Then 331 if ((isVectorType(Ty) || isScalarFloatingType(Ty))) {
362 // generate an instruction in the prolog to copy the home register 332 if (NumXmmArgs >= Traits::X86_MAX_XMM_ARGS) {
363 // to the assigned location of Arg. 333 continue;
364 int32_t RegNum = getRegisterForXmmArgNum(NumXmmArgs); 334 }
335 RegNum = getRegisterForXmmArgNum(NumXmmArgs);
365 ++NumXmmArgs; 336 ++NumXmmArgs;
366 Variable *RegisterArg = Func->makeVariable(Ty); 337 RegisterArg = Func->makeVariable(Ty);
367 if (BuildDefs::dump()) 338 } else if (isScalarIntegerType(Ty)) {
368 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func)); 339 if (NumGprArgs >= Traits::X86_MAX_GPR_ARGS) {
369 RegisterArg->setRegNum(RegNum); 340 continue;
370 RegisterArg->setIsArg(); 341 }
371 Arg->setIsArg(false); 342 RegNum = getRegisterForGprArgNum(NumGprArgs);
343 ++NumGprArgs;
344 RegisterArg = Func->makeVariable(Ty);
345 }
346 assert(RegNum != -1);
347 assert(RegisterArg != nullptr);
348 // Replace Arg in the argument list with the home register. Then
349 // generate an instruction in the prolog to copy the home register
350 // to the assigned location of Arg.
351 if (BuildDefs::dump())
352 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func));
353 RegisterArg->setRegNum(RegNum);
354 RegisterArg->setIsArg();
355 Arg->setIsArg(false);
372 356
373 Args[i] = RegisterArg; 357 Args[i] = RegisterArg;
374 Context.insert(InstAssign::create(Func, Arg, RegisterArg)); 358 Context.insert(InstAssign::create(Func, Arg, RegisterArg));
375 } else if (isScalarIntegerType(Ty) &&
376 NumGprArgs < Traits::X86_MAX_GPR_ARGS) {
377 int32_t RegNum = getRegisterForGprArgNum(NumGprArgs);
378 ++NumGprArgs;
379 Variable *RegisterArg = Func->makeVariable(Ty);
380 if (BuildDefs::dump())
381 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func));
382 RegisterArg->setRegNum(RegNum);
383 RegisterArg->setIsArg();
384 Arg->setIsArg(false);
385
386 Args[i] = RegisterArg;
387 Context.insert(InstAssign::create(Func, Arg, RegisterArg));
388 }
389 } 359 }
390 } 360 }
391 361
392 void TargetX8664::lowerRet(const InstRet *Inst) { 362 void TargetX8664::lowerRet(const InstRet *Inst) {
393 Variable *Reg = nullptr; 363 Variable *Reg = nullptr;
394 if (Inst->hasRetValue()) { 364 if (Inst->hasRetValue()) {
395 Operand *Src0 = legalize(Inst->getRetValue()); 365 Operand *Src0 = legalize(Inst->getRetValue());
396 // TODO(jpp): this is not needed. 366 if (isVectorType(Src0->getType()) ||
397 if (Src0->getType() == IceType_i64) { 367 isScalarFloatingType(Src0->getType())) {
398 Variable *eax =
399 legalizeToReg(loOperand(Src0), Traits::RegisterSet::Reg_eax);
400 Variable *edx =
401 legalizeToReg(hiOperand(Src0), Traits::RegisterSet::Reg_edx);
402 Reg = eax;
403 Context.insert(InstFakeUse::create(Func, edx));
404 } else if (isScalarFloatingType(Src0->getType())) {
405 _fld(Src0);
406 } else if (isVectorType(Src0->getType())) {
407 Reg = legalizeToReg(Src0, Traits::RegisterSet::Reg_xmm0); 368 Reg = legalizeToReg(Src0, Traits::RegisterSet::Reg_xmm0);
408 } else { 369 } else {
370 assert(isScalarIntegerType(Src0->getType()));
409 _mov(Reg, Src0, Traits::RegisterSet::Reg_eax); 371 _mov(Reg, Src0, Traits::RegisterSet::Reg_eax);
410 } 372 }
411 } 373 }
412 // Add a ret instruction even if sandboxing is enabled, because 374 // Add a ret instruction even if sandboxing is enabled, because
413 // addEpilog explicitly looks for a ret instruction as a marker for 375 // addEpilog explicitly looks for a ret instruction as a marker for
414 // where to insert the frame removal instructions. 376 // where to insert the frame removal instructions.
415 _ret(Reg); 377 _ret(Reg);
416 // Add a fake use of esp to make sure esp stays alive for the entire 378 // Add a fake use of esp to make sure esp stays alive for the entire
417 // function. Otherwise post-call esp adjustments get dead-code 379 // function. Otherwise post-call esp adjustments get dead-code
418 // eliminated. TODO: Are there more places where the fake use 380 // eliminated. TODO: Are there more places where the fake use
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 PreservedRegsSizeBytes + Traits::X86_RET_IP_SIZE_BYTES; 532 PreservedRegsSizeBytes + Traits::X86_RET_IP_SIZE_BYTES;
571 if (!IsEbpBasedFrame) 533 if (!IsEbpBasedFrame)
572 BasicFrameOffset += SpillAreaSizeBytes; 534 BasicFrameOffset += SpillAreaSizeBytes;
573 535
574 const VarList &Args = Func->getArgs(); 536 const VarList &Args = Func->getArgs();
575 size_t InArgsSizeBytes = 0; 537 size_t InArgsSizeBytes = 0;
576 unsigned NumXmmArgs = 0; 538 unsigned NumXmmArgs = 0;
577 unsigned NumGPRArgs = 0; 539 unsigned NumGPRArgs = 0;
578 for (Variable *Arg : Args) { 540 for (Variable *Arg : Args) {
579 // Skip arguments passed in registers. 541 // Skip arguments passed in registers.
580 if (isVectorType(Arg->getType()) && NumXmmArgs < Traits::X86_MAX_XMM_ARGS) { 542 if (isVectorType(Arg->getType()) || isScalarFloatingType(Arg->getType())) {
581 ++NumXmmArgs; 543 if (NumXmmArgs < Traits::X86_MAX_XMM_ARGS) {
582 continue; 544 ++NumXmmArgs;
583 } 545 continue;
584 if (isScalarFloatingType(Arg->getType()) && 546 }
585 NumXmmArgs < Traits::X86_MAX_XMM_ARGS) { 547 } else {
586 ++NumXmmArgs; 548 assert(isScalarIntegerType(Arg->getType()));
587 continue; 549 if (NumGPRArgs < Traits::X86_MAX_GPR_ARGS) {
588 } 550 ++NumGPRArgs;
589 if (isScalarIntegerType(Arg->getType()) && 551 continue;
590 NumGPRArgs < Traits::X86_MAX_GPR_ARGS) { 552 }
591 ++NumGPRArgs;
592 continue;
593 } 553 }
594 finishArgumentLowering(Arg, FramePtr, BasicFrameOffset, InArgsSizeBytes); 554 finishArgumentLowering(Arg, FramePtr, BasicFrameOffset, InArgsSizeBytes);
595 } 555 }
596 556
597 // Fill in stack offsets for locals. 557 // Fill in stack offsets for locals.
598 assignVarStackSlots(SortedSpilledVariables, SpillAreaPaddingBytes, 558 assignVarStackSlots(SortedSpilledVariables, SpillAreaPaddingBytes,
599 SpillAreaSizeBytes, GlobalsAndSubsequentPaddingSize, 559 SpillAreaSizeBytes, GlobalsAndSubsequentPaddingSize,
600 IsEbpBasedFrame); 560 IsEbpBasedFrame);
601 // Assign stack offsets to variables that have been linked to spilled 561 // Assign stack offsets to variables that have been linked to spilled
602 // variables. 562 // variables.
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 getRegisterSet(RegSet_CalleeSave, RegSet_None); 632 getRegisterSet(RegSet_CalleeSave, RegSet_None);
673 for (SizeT i = 0; i < CalleeSaves.size(); ++i) { 633 for (SizeT i = 0; i < CalleeSaves.size(); ++i) {
674 SizeT j = CalleeSaves.size() - i - 1; 634 SizeT j = CalleeSaves.size() - i - 1;
675 if (j == Traits::RegisterSet::Reg_ebp && IsEbpBasedFrame) 635 if (j == Traits::RegisterSet::Reg_ebp && IsEbpBasedFrame)
676 continue; 636 continue;
677 if (CalleeSaves[j] && RegsUsed[j]) { 637 if (CalleeSaves[j] && RegsUsed[j]) {
678 _pop(getPhysicalRegister(j)); 638 _pop(getPhysicalRegister(j));
679 } 639 }
680 } 640 }
681 641
682 if (!Ctx->getFlags().getUseSandboxing()) 642 if (Ctx->getFlags().getUseSandboxing()) {
683 return; 643 llvm_unreachable("X86-64 Sandboxing codegen not implemented.");
684 // Change the original ret instruction into a sandboxed return sequence.
685 // t:ecx = pop
686 // bundle_lock
687 // and t, ~31
688 // jmp *t
689 // bundle_unlock
690 // FakeUse <original_ret_operand>
691 Variable *T_ecx = makeReg(IceType_i32, Traits::RegisterSet::Reg_ecx);
692 _pop(T_ecx);
693 lowerIndirectJump(T_ecx);
694 if (RI->getSrcSize()) {
695 Variable *RetValue = llvm::cast<Variable>(RI->getSrc(0));
696 Context.insert(InstFakeUse::create(Func, RetValue));
697 } 644 }
698 RI->setDeleted();
699 } 645 }
700 646
701 void TargetX8664::emitJumpTable(const Cfg *Func, 647 void TargetX8664::emitJumpTable(const Cfg *Func,
702 const InstJumpTable *JumpTable) const { 648 const InstJumpTable *JumpTable) const {
703 if (!BuildDefs::dump()) 649 if (!BuildDefs::dump())
704 return; 650 return;
705 Ostream &Str = Ctx->getStrEmit(); 651 Ostream &Str = Ctx->getStrEmit();
706 IceString MangledName = Ctx->mangleName(Func->getFunctionName()); 652 IceString MangledName = Ctx->mangleName(Func->getFunctionName());
707 Str << "\t.section\t.rodata." << MangledName 653 Str << "\t.section\t.rodata." << MangledName
708 << "$jumptable,\"a\",@progbits\n"; 654 << "$jumptable,\"a\",@progbits\n";
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
851 emitConstantPool<PoolTypeConverter<double>>(Ctx); 797 emitConstantPool<PoolTypeConverter<double>>(Ctx);
852 } break; 798 } break;
853 } 799 }
854 } 800 }
855 801
856 void TargetDataX8664::lowerJumpTables() { 802 void TargetDataX8664::lowerJumpTables() {
857 switch (Ctx->getFlags().getOutFileType()) { 803 switch (Ctx->getFlags().getOutFileType()) {
858 case FT_Elf: { 804 case FT_Elf: {
859 ELFObjectWriter *Writer = Ctx->getObjectWriter(); 805 ELFObjectWriter *Writer = Ctx->getObjectWriter();
860 for (const JumpTableData &JumpTable : Ctx->getJumpTables()) 806 for (const JumpTableData &JumpTable : Ctx->getJumpTables())
861 // TODO(jpp): not 386. 807 Writer->writeJumpTable(JumpTable, TargetX8664::Traits::RelFixup);
862 Writer->writeJumpTable(JumpTable, llvm::ELF::R_386_32);
863 } break; 808 } break;
864 case FT_Asm: 809 case FT_Asm:
865 // Already emitted from Cfg 810 // Already emitted from Cfg
866 break; 811 break;
867 case FT_Iasm: { 812 case FT_Iasm: {
868 if (!BuildDefs::dump()) 813 if (!BuildDefs::dump())
869 return; 814 return;
870 Ostream &Str = Ctx->getStrEmit(); 815 Ostream &Str = Ctx->getStrEmit();
871 for (const JumpTableData &JT : Ctx->getJumpTables()) { 816 for (const JumpTableData &JT : Ctx->getJumpTables()) {
872 Str << "\t.section\t.rodata." << JT.getFunctionName() 817 Str << "\t.section\t.rodata." << JT.getFunctionName()
873 << "$jumptable,\"a\",@progbits\n"; 818 << "$jumptable,\"a\",@progbits\n";
874 Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n"; 819 Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n";
875 Str << InstJumpTable::makeName(JT.getFunctionName(), JT.getId()) << ":"; 820 Str << InstJumpTable::makeName(JT.getFunctionName(), JT.getId()) << ":";
876 821
877 // On X8664 ILP32 pointers are 32-bit hence the use of .long 822 // On X8664 ILP32 pointers are 32-bit hence the use of .long
878 for (intptr_t TargetOffset : JT.getTargetOffsets()) 823 for (intptr_t TargetOffset : JT.getTargetOffsets())
879 Str << "\n\t.long\t" << JT.getFunctionName() << "+" << TargetOffset; 824 Str << "\n\t.long\t" << JT.getFunctionName() << "+" << TargetOffset;
880 Str << "\n"; 825 Str << "\n";
881 } 826 }
882 } break; 827 } break;
883 } 828 }
884 } 829 }
885 830
886 void TargetDataX8664::lowerGlobals(const VariableDeclarationList &Vars, 831 void TargetDataX8664::lowerGlobals(const VariableDeclarationList &Vars,
887 const IceString &SectionSuffix) { 832 const IceString &SectionSuffix) {
888 switch (Ctx->getFlags().getOutFileType()) { 833 switch (Ctx->getFlags().getOutFileType()) {
889 case FT_Elf: { 834 case FT_Elf: {
890 ELFObjectWriter *Writer = Ctx->getObjectWriter(); 835 ELFObjectWriter *Writer = Ctx->getObjectWriter();
891 // TODO(jpp): not 386. 836 Writer->writeDataSection(Vars, TargetX8664::Traits::RelFixup,
892 Writer->writeDataSection(Vars, llvm::ELF::R_386_32, SectionSuffix); 837 SectionSuffix);
893 } break; 838 } break;
894 case FT_Asm: 839 case FT_Asm:
895 case FT_Iasm: { 840 case FT_Iasm: {
896 const IceString &TranslateOnly = Ctx->getFlags().getTranslateOnly(); 841 const IceString &TranslateOnly = Ctx->getFlags().getTranslateOnly();
897 OstreamLocker L(Ctx); 842 OstreamLocker L(Ctx);
898 for (const VariableDeclaration *Var : Vars) { 843 for (const VariableDeclaration *Var : Vars) {
899 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) { 844 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) {
900 emitGlobal(*Var, SectionSuffix); 845 emitGlobal(*Var, SectionSuffix);
901 } 846 }
902 } 847 }
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1006 // entries in case the high-level table has extra entries. 951 // entries in case the high-level table has extra entries.
1007 #define X(tag, sizeLog2, align, elts, elty, str) \ 952 #define X(tag, sizeLog2, align, elts, elty, str) \
1008 static_assert(_table1_##tag == _table2_##tag, \ 953 static_assert(_table1_##tag == _table2_##tag, \
1009 "Inconsistency between ICETYPEX8664_TABLE and ICETYPE_TABLE"); 954 "Inconsistency between ICETYPEX8664_TABLE and ICETYPE_TABLE");
1010 ICETYPE_TABLE 955 ICETYPE_TABLE
1011 #undef X 956 #undef X
1012 } // end of namespace dummy3 957 } // end of namespace dummy3
1013 } // end of anonymous namespace 958 } // end of anonymous namespace
1014 959
1015 } // end of namespace Ice 960 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698