Chromium Code Reviews| Index: src/IceInstX8632.cpp |
| diff --git a/src/IceInstX8632.cpp b/src/IceInstX8632.cpp |
| index 72d75458f7153317f42bea8fcf30132c60be3bee..b329d0cc70b4f4d3c4d486966b81d5e64f5f225e 100644 |
| --- a/src/IceInstX8632.cpp |
| +++ b/src/IceInstX8632.cpp |
| @@ -346,9 +346,9 @@ void emitIASBytes(Ostream &Str, const x86::AssemblerX86 *Asm, |
| if (LastFixupLoc < StartPosition) { |
| // The fixup doesn't apply to this current block. |
| for (intptr_t i = 0; i < EndPosition - StartPosition; ++i) { |
| - Str << "\t.byte " |
| - << static_cast<uint32_t>(Asm->LoadBuffer<uint8_t>(StartPosition + i)) |
| - << "\n"; |
| + Str << "\t.byte 0x"; |
| + Str.write_hex(Asm->LoadBuffer<uint8_t>(StartPosition + i)); |
|
Jim Stichnoth
2014/09/26 02:31:36
Thanks! :)
|
| + Str << "\n"; |
| } |
| return; |
| } |
| @@ -356,9 +356,9 @@ void emitIASBytes(Ostream &Str, const x86::AssemblerX86 *Asm, |
| assert(LastFixupLoc + FixupSize <= EndPosition); |
| // The fixup does apply to this current block. |
| for (intptr_t i = 0; i < LastFixupLoc - StartPosition; ++i) { |
| - Str << "\t.byte " |
| - << static_cast<uint32_t>(Asm->LoadBuffer<uint8_t>(StartPosition + i)) |
| - << "\n"; |
| + Str << "\t.byte 0x"; |
| + Str.write_hex(Asm->LoadBuffer<uint8_t>(StartPosition + i)); |
| + Str << "\n"; |
| } |
| Str << "\t.long " << LastFixup->value()->getName(); |
| if (LastFixup->value()->getOffset()) { |
| @@ -366,8 +366,9 @@ void emitIASBytes(Ostream &Str, const x86::AssemblerX86 *Asm, |
| } |
| Str << "\n"; |
| for (intptr_t i = LastFixupLoc + FixupSize; i < EndPosition; ++i) { |
| - Str << "\t.byte " << static_cast<uint32_t>(Asm->LoadBuffer<uint8_t>(i)) |
| - << "\n"; |
| + Str << "\t.byte 0x"; |
| + Str.write_hex(Asm->LoadBuffer<uint8_t>(StartPosition + i)); |
| + Str << "\n"; |
| } |
| } |
| @@ -478,19 +479,25 @@ void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func, |
| Str << "\n"; |
| } |
| -void emitIASVarTyGPR(const Cfg *Func, Type Ty, const Variable *Var, |
| - const x86::AssemblerX86::GPREmitterOneOp &Emitter) { |
| +void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op, |
| + const x86::AssemblerX86::GPREmitterOneOp &Emitter) { |
| x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| intptr_t StartPosition = Asm->GetPosition(); |
| - if (Var->hasReg()) { |
| - // We cheat a little and use GPRRegister even for byte operations. |
| - RegX8632::GPRRegister VarReg = |
| - RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); |
| - (Asm->*(Emitter.Reg))(Ty, VarReg); |
| + if (const Variable *Var = llvm::dyn_cast<Variable>(Op)) { |
| + if (Var->hasReg()) { |
| + // We cheat a little and use GPRRegister even for byte operations. |
| + RegX8632::GPRRegister VarReg = |
| + RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); |
| + (Asm->*(Emitter.Reg))(Ty, VarReg); |
| + } else { |
| + x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| + ->stackVarToAsmOperand(Var)); |
| + (Asm->*(Emitter.Addr))(Ty, StackAddr); |
| + } |
| + } else if (const OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Op)) { |
| + (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Asm)); |
| } else { |
| - x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| - ->stackVarToAsmOperand(Var)); |
| - (Asm->*(Emitter.Addr))(Ty, StackAddr); |
| + llvm_unreachable("Unexpected operand type"); |
| } |
| Ostream &Str = Func->getContext()->getStrEmit(); |
| emitIASBytes(Str, Asm, StartPosition); |
| @@ -666,6 +673,29 @@ template <> |
| const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Sqrtss::Emitter = { |
| &x86::AssemblerX86::sqrtss, &x86::AssemblerX86::sqrtss, NULL}; |
| +// Binary GPR ops |
| +template <> |
| +const x86::AssemblerX86::GPREmitterRegOp InstX8632Add::Emitter = { |
| + &x86::AssemblerX86::add, &x86::AssemblerX86::add, &x86::AssemblerX86::add}; |
| +template <> |
| +const x86::AssemblerX86::GPREmitterRegOp InstX8632Adc::Emitter = { |
| + &x86::AssemblerX86::adc, &x86::AssemblerX86::adc, &x86::AssemblerX86::adc}; |
| +template <> |
| +const x86::AssemblerX86::GPREmitterRegOp InstX8632And::Emitter = { |
| + &x86::AssemblerX86::And, &x86::AssemblerX86::And, &x86::AssemblerX86::And}; |
| +template <> |
| +const x86::AssemblerX86::GPREmitterRegOp InstX8632Or::Emitter = { |
| + &x86::AssemblerX86::Or, &x86::AssemblerX86::Or, &x86::AssemblerX86::Or}; |
| +template <> |
| +const x86::AssemblerX86::GPREmitterRegOp InstX8632Sbb::Emitter = { |
| + &x86::AssemblerX86::sbb, &x86::AssemblerX86::sbb, &x86::AssemblerX86::sbb}; |
| +template <> |
| +const x86::AssemblerX86::GPREmitterRegOp InstX8632Sub::Emitter = { |
| + &x86::AssemblerX86::sub, &x86::AssemblerX86::sub, &x86::AssemblerX86::sub}; |
| +template <> |
| +const x86::AssemblerX86::GPREmitterRegOp InstX8632Xor::Emitter = { |
| + &x86::AssemblerX86::Xor, &x86::AssemblerX86::Xor, &x86::AssemblerX86::Xor}; |
| + |
| // Binary XMM ops |
| template <> |
| const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Addss::Emitter = { |
| @@ -798,6 +828,15 @@ template <> void InstX8632Div::emit(const Cfg *Func) const { |
| Str << "\n"; |
| } |
| +template <> void InstX8632Div::emitIAS(const Cfg *Func) const { |
| + assert(getSrcSize() == 3); |
| + const Operand *Src = getSrc(1); |
| + Type Ty = Src->getType(); |
| + const static x86::AssemblerX86::GPREmitterOneOp Emitter = { |
| + &x86::AssemblerX86::div, &x86::AssemblerX86::div}; |
| + emitIASOpTyGPR(Func, Ty, Src, Emitter); |
| +} |
| + |
| template <> void InstX8632Idiv::emit(const Cfg *Func) const { |
| Ostream &Str = Func->getContext()->getStrEmit(); |
| assert(getSrcSize() == 3); |
| @@ -806,6 +845,14 @@ template <> void InstX8632Idiv::emit(const Cfg *Func) const { |
| Str << "\n"; |
| } |
| +template <> void InstX8632Idiv::emitIAS(const Cfg *Func) const { |
| + assert(getSrcSize() == 3); |
| + const Operand *Src = getSrc(1); |
| + Type Ty = Src->getType(); |
| + const static x86::AssemblerX86::GPREmitterOneOp Emitter = { |
| + &x86::AssemblerX86::idiv, &x86::AssemblerX86::idiv}; |
| + emitIASOpTyGPR(Func, Ty, Src, Emitter); |
| +} |
| namespace { |
| @@ -926,6 +973,18 @@ void InstX8632Mul::emit(const Cfg *Func) const { |
| Str << "\n"; |
| } |
| +void InstX8632Mul::emitIAS(const Cfg *Func) const { |
| + assert(getSrcSize() == 2); |
| + assert(llvm::isa<Variable>(getSrc(0))); |
| + assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); |
| + assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? |
| + const Operand *Src = getSrc(1); |
| + Type Ty = Src->getType(); |
| + const static x86::AssemblerX86::GPREmitterOneOp Emitter = { |
| + &x86::AssemblerX86::mul, &x86::AssemblerX86::mul}; |
| + emitIASOpTyGPR(Func, Ty, Src, Emitter); |
| +} |
| + |
| void InstX8632Mul::dump(const Cfg *Func) const { |
| Ostream &Str = Func->getContext()->getStrDump(); |
| dumpDest(Func); |
| @@ -1246,6 +1305,14 @@ void InstX8632Mfence::emit(const Cfg *Func) const { |
| Str << "\tmfence\n"; |
| } |
| +void InstX8632Mfence::emitIAS(const Cfg *Func) const { |
| + Ostream &Str = Func->getContext()->getStrEmit(); |
| + x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| + intptr_t StartPosition = Asm->GetPosition(); |
| + Asm->mfence(); |
| + emitIASBytes(Str, Asm, StartPosition); |
| +} |
| + |
| void InstX8632Mfence::dump(const Cfg *Func) const { |
| Ostream &Str = Func->getContext()->getStrDump(); |
| Str << "mfence\n"; |
| @@ -1661,7 +1728,7 @@ void InstX8632AdjustStack::emitIAS(const Cfg *Func) const { |
| Ostream &Str = Func->getContext()->getStrEmit(); |
| x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| intptr_t StartPosition = Asm->GetPosition(); |
| - Asm->subl(RegX8632::Encoded_Reg_esp, x86::Immediate(Amount)); |
| + Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, x86::Immediate(Amount)); |
| emitIASBytes(Str, Asm, StartPosition); |
| Func->getTarget()->updateStackAdjustment(Amount); |
| } |