| Index: src/IceInstX8632.cpp
|
| diff --git a/src/IceInstX8632.cpp b/src/IceInstX8632.cpp
|
| index 72d75458f7153317f42bea8fcf30132c60be3bee..0ea67b973b14c2b9402568b918a5e9a81be0c6b2 100644
|
| --- a/src/IceInstX8632.cpp
|
| +++ b/src/IceInstX8632.cpp
|
| @@ -345,20 +345,20 @@ 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";
|
| + for (intptr_t i = StartPosition; i < EndPosition; ++i) {
|
| + Str << "\t.byte 0x";
|
| + Str.write_hex(Asm->LoadBuffer<uint8_t>(i));
|
| + Str << "\n";
|
| }
|
| return;
|
| }
|
| const intptr_t FixupSize = 4;
|
| 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";
|
| + for (intptr_t i = StartPosition; i < LastFixupLoc; ++i) {
|
| + Str << "\t.byte 0x";
|
| + Str.write_hex(Asm->LoadBuffer<uint8_t>(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>(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);
|
| }
|
|
|