mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-17 18:24:34 +00:00
Delete unused EmitByteSwap method
Implement mul/div/rem constant expressions git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@9424 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -192,10 +192,6 @@ namespace {
|
|||||||
///
|
///
|
||||||
void promote32(unsigned targetReg, const ValueRecord &VR);
|
void promote32(unsigned targetReg, const ValueRecord &VR);
|
||||||
|
|
||||||
/// EmitByteSwap - Byteswap SrcReg into DestReg.
|
|
||||||
///
|
|
||||||
void EmitByteSwap(unsigned DestReg, unsigned SrcReg, unsigned Class);
|
|
||||||
|
|
||||||
/// emitGEPOperation - Common code shared between visitGetElementPtrInst and
|
/// emitGEPOperation - Common code shared between visitGetElementPtrInst and
|
||||||
/// constant expression GEP support.
|
/// constant expression GEP support.
|
||||||
///
|
///
|
||||||
@@ -215,6 +211,11 @@ namespace {
|
|||||||
Value *Op0, Value *Op1,
|
Value *Op0, Value *Op1,
|
||||||
unsigned OperatorClass, unsigned TargetReg);
|
unsigned OperatorClass, unsigned TargetReg);
|
||||||
|
|
||||||
|
void emitDivRemOperation(MachineBasicBlock *BB,
|
||||||
|
MachineBasicBlock::iterator &IP,
|
||||||
|
unsigned Op0Reg, unsigned Op1Reg, bool isDiv,
|
||||||
|
const Type *Ty, unsigned TargetReg);
|
||||||
|
|
||||||
/// emitSetCCOperation - Common code shared between visitSetCondInst and
|
/// emitSetCCOperation - Common code shared between visitSetCondInst and
|
||||||
/// constant expression support.
|
/// constant expression support.
|
||||||
void emitSetCCOperation(MachineBasicBlock *BB,
|
void emitSetCCOperation(MachineBasicBlock *BB,
|
||||||
@@ -355,6 +356,22 @@ void ISel::copyConstantToRegister(MachineBasicBlock *MBB,
|
|||||||
Class, R);
|
Class, R);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case Instruction::Mul: {
|
||||||
|
unsigned Op0Reg = getReg(CE->getOperand(0), MBB, IP);
|
||||||
|
unsigned Op1Reg = getReg(CE->getOperand(1), MBB, IP);
|
||||||
|
doMultiply(MBB, IP, R, CE->getType(), Op0Reg, Op1Reg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case Instruction::Div:
|
||||||
|
case Instruction::Rem: {
|
||||||
|
unsigned Op0Reg = getReg(CE->getOperand(0), MBB, IP);
|
||||||
|
unsigned Op1Reg = getReg(CE->getOperand(1), MBB, IP);
|
||||||
|
emitDivRemOperation(MBB, IP, Op0Reg, Op1Reg,
|
||||||
|
CE->getOpcode() == Instruction::Div,
|
||||||
|
CE->getType(), R);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case Instruction::SetNE:
|
case Instruction::SetNE:
|
||||||
case Instruction::SetEQ:
|
case Instruction::SetEQ:
|
||||||
case Instruction::SetLT:
|
case Instruction::SetLT:
|
||||||
@@ -1339,21 +1356,30 @@ void ISel::visitMul(BinaryOperator &I) {
|
|||||||
/// instructions work differently for signed and unsigned operands.
|
/// instructions work differently for signed and unsigned operands.
|
||||||
///
|
///
|
||||||
void ISel::visitDivRem(BinaryOperator &I) {
|
void ISel::visitDivRem(BinaryOperator &I) {
|
||||||
unsigned Class = getClass(I.getType());
|
unsigned Op0Reg = getReg(I.getOperand(0));
|
||||||
unsigned Op0Reg, Op1Reg, ResultReg = getReg(I);
|
unsigned Op1Reg = getReg(I.getOperand(1));
|
||||||
|
unsigned ResultReg = getReg(I);
|
||||||
|
|
||||||
|
MachineBasicBlock::iterator IP = BB->end();
|
||||||
|
emitDivRemOperation(BB, IP, Op0Reg, Op1Reg, I.getOpcode() == Instruction::Div,
|
||||||
|
I.getType(), ResultReg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ISel::emitDivRemOperation(MachineBasicBlock *BB,
|
||||||
|
MachineBasicBlock::iterator &IP,
|
||||||
|
unsigned Op0Reg, unsigned Op1Reg, bool isDiv,
|
||||||
|
const Type *Ty, unsigned ResultReg) {
|
||||||
|
unsigned Class = getClass(Ty);
|
||||||
switch (Class) {
|
switch (Class) {
|
||||||
case cFP: // Floating point divide
|
case cFP: // Floating point divide
|
||||||
if (I.getOpcode() == Instruction::Div) {
|
if (isDiv) {
|
||||||
Op0Reg = getReg(I.getOperand(0));
|
|
||||||
Op1Reg = getReg(I.getOperand(1));
|
|
||||||
BuildMI(BB, X86::FpDIV, 2, ResultReg).addReg(Op0Reg).addReg(Op1Reg);
|
BuildMI(BB, X86::FpDIV, 2, ResultReg).addReg(Op0Reg).addReg(Op1Reg);
|
||||||
} else { // Floating point remainder...
|
} else { // Floating point remainder...
|
||||||
MachineInstr *TheCall =
|
MachineInstr *TheCall =
|
||||||
BuildMI(X86::CALLpcrel32, 1).addExternalSymbol("fmod", true);
|
BuildMI(X86::CALLpcrel32, 1).addExternalSymbol("fmod", true);
|
||||||
std::vector<ValueRecord> Args;
|
std::vector<ValueRecord> Args;
|
||||||
Args.push_back(ValueRecord(I.getOperand(0)));
|
Args.push_back(ValueRecord(Op0Reg, Type::DoubleTy));
|
||||||
Args.push_back(ValueRecord(I.getOperand(1)));
|
Args.push_back(ValueRecord(Op1Reg, Type::DoubleTy));
|
||||||
doCall(ValueRecord(ResultReg, Type::DoubleTy), TheCall, Args);
|
doCall(ValueRecord(ResultReg, Type::DoubleTy), TheCall, Args);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -1361,14 +1387,13 @@ void ISel::visitDivRem(BinaryOperator &I) {
|
|||||||
static const char *FnName[] =
|
static const char *FnName[] =
|
||||||
{ "__moddi3", "__divdi3", "__umoddi3", "__udivdi3" };
|
{ "__moddi3", "__divdi3", "__umoddi3", "__udivdi3" };
|
||||||
|
|
||||||
unsigned NameIdx = I.getType()->isUnsigned()*2;
|
unsigned NameIdx = Ty->isUnsigned()*2 + isDiv;
|
||||||
NameIdx += I.getOpcode() == Instruction::Div;
|
|
||||||
MachineInstr *TheCall =
|
MachineInstr *TheCall =
|
||||||
BuildMI(X86::CALLpcrel32, 1).addExternalSymbol(FnName[NameIdx], true);
|
BuildMI(X86::CALLpcrel32, 1).addExternalSymbol(FnName[NameIdx], true);
|
||||||
|
|
||||||
std::vector<ValueRecord> Args;
|
std::vector<ValueRecord> Args;
|
||||||
Args.push_back(ValueRecord(I.getOperand(0)));
|
Args.push_back(ValueRecord(Op0Reg, Type::LongTy));
|
||||||
Args.push_back(ValueRecord(I.getOperand(1)));
|
Args.push_back(ValueRecord(Op1Reg, Type::LongTy));
|
||||||
doCall(ValueRecord(ResultReg, Type::LongTy), TheCall, Args);
|
doCall(ValueRecord(ResultReg, Type::LongTy), TheCall, Args);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1388,17 +1413,16 @@ void ISel::visitDivRem(BinaryOperator &I) {
|
|||||||
{ X86::IDIVr8, X86::IDIVr16, X86::IDIVr32, 0 }, // Signed division
|
{ X86::IDIVr8, X86::IDIVr16, X86::IDIVr32, 0 }, // Signed division
|
||||||
};
|
};
|
||||||
|
|
||||||
bool isSigned = I.getType()->isSigned();
|
bool isSigned = Ty->isSigned();
|
||||||
unsigned Reg = Regs[Class];
|
unsigned Reg = Regs[Class];
|
||||||
unsigned ExtReg = ExtRegs[Class];
|
unsigned ExtReg = ExtRegs[Class];
|
||||||
|
|
||||||
// Put the first operand into one of the A registers...
|
// Put the first operand into one of the A registers...
|
||||||
Op0Reg = getReg(I.getOperand(0));
|
|
||||||
BuildMI(BB, MovOpcode[Class], 1, Reg).addReg(Op0Reg);
|
BuildMI(BB, MovOpcode[Class], 1, Reg).addReg(Op0Reg);
|
||||||
|
|
||||||
if (isSigned) {
|
if (isSigned) {
|
||||||
// Emit a sign extension instruction...
|
// Emit a sign extension instruction...
|
||||||
unsigned ShiftResult = makeAnotherReg(I.getType());
|
unsigned ShiftResult = makeAnotherReg(Ty);
|
||||||
BuildMI(BB, SarOpcode[Class], 2, ShiftResult).addReg(Op0Reg).addZImm(31);
|
BuildMI(BB, SarOpcode[Class], 2, ShiftResult).addReg(Op0Reg).addZImm(31);
|
||||||
BuildMI(BB, MovOpcode[Class], 1, ExtReg).addReg(ShiftResult);
|
BuildMI(BB, MovOpcode[Class], 1, ExtReg).addReg(ShiftResult);
|
||||||
} else {
|
} else {
|
||||||
@@ -1407,11 +1431,10 @@ void ISel::visitDivRem(BinaryOperator &I) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Emit the appropriate divide or remainder instruction...
|
// Emit the appropriate divide or remainder instruction...
|
||||||
Op1Reg = getReg(I.getOperand(1));
|
|
||||||
BuildMI(BB, DivOpcode[isSigned][Class], 1).addReg(Op1Reg);
|
BuildMI(BB, DivOpcode[isSigned][Class], 1).addReg(Op1Reg);
|
||||||
|
|
||||||
// Figure out which register we want to pick the result out of...
|
// Figure out which register we want to pick the result out of...
|
||||||
unsigned DestReg = (I.getOpcode() == Instruction::Div) ? Reg : ExtReg;
|
unsigned DestReg = isDiv ? Reg : ExtReg;
|
||||||
|
|
||||||
// Put the result into the destination register...
|
// Put the result into the destination register...
|
||||||
BuildMI(BB, MovOpcode[Class], 1, ResultReg).addReg(DestReg);
|
BuildMI(BB, MovOpcode[Class], 1, ResultReg).addReg(DestReg);
|
||||||
@@ -1544,35 +1567,6 @@ void ISel::visitShiftInst(ShiftInst &I) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// EmitByteSwap - Byteswap SrcReg into DestReg.
|
|
||||||
///
|
|
||||||
void ISel::EmitByteSwap(unsigned DestReg, unsigned SrcReg, unsigned Class) {
|
|
||||||
// Emit the byte swap instruction...
|
|
||||||
switch (Class) {
|
|
||||||
case cByte:
|
|
||||||
// No byteswap necessary for 8 bit value...
|
|
||||||
BuildMI(BB, X86::MOVrr8, 1, DestReg).addReg(SrcReg);
|
|
||||||
break;
|
|
||||||
case cInt:
|
|
||||||
// Use the 32 bit bswap instruction to do a 32 bit swap...
|
|
||||||
BuildMI(BB, X86::BSWAPr32, 1, DestReg).addReg(SrcReg);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case cShort:
|
|
||||||
// For 16 bit we have to use an xchg instruction, because there is no
|
|
||||||
// 16-bit bswap. XCHG is necessarily not in SSA form, so we force things
|
|
||||||
// into AX to do the xchg.
|
|
||||||
//
|
|
||||||
BuildMI(BB, X86::MOVrr16, 1, X86::AX).addReg(SrcReg);
|
|
||||||
BuildMI(BB, X86::XCHGrr8, 2).addReg(X86::AL, MOTy::UseAndDef)
|
|
||||||
.addReg(X86::AH, MOTy::UseAndDef);
|
|
||||||
BuildMI(BB, X86::MOVrr16, 1, DestReg).addReg(X86::AX);
|
|
||||||
break;
|
|
||||||
default: assert(0 && "Cannot byteswap this class!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// visitLoadInst - Implement LLVM load instructions in terms of the x86 'mov'
|
/// visitLoadInst - Implement LLVM load instructions in terms of the x86 'mov'
|
||||||
/// instruction. The load and store instructions are the only place where we
|
/// instruction. The load and store instructions are the only place where we
|
||||||
/// need to worry about the memory layout of the target machine.
|
/// need to worry about the memory layout of the target machine.
|
||||||
|
@@ -192,10 +192,6 @@ namespace {
|
|||||||
///
|
///
|
||||||
void promote32(unsigned targetReg, const ValueRecord &VR);
|
void promote32(unsigned targetReg, const ValueRecord &VR);
|
||||||
|
|
||||||
/// EmitByteSwap - Byteswap SrcReg into DestReg.
|
|
||||||
///
|
|
||||||
void EmitByteSwap(unsigned DestReg, unsigned SrcReg, unsigned Class);
|
|
||||||
|
|
||||||
/// emitGEPOperation - Common code shared between visitGetElementPtrInst and
|
/// emitGEPOperation - Common code shared between visitGetElementPtrInst and
|
||||||
/// constant expression GEP support.
|
/// constant expression GEP support.
|
||||||
///
|
///
|
||||||
@@ -215,6 +211,11 @@ namespace {
|
|||||||
Value *Op0, Value *Op1,
|
Value *Op0, Value *Op1,
|
||||||
unsigned OperatorClass, unsigned TargetReg);
|
unsigned OperatorClass, unsigned TargetReg);
|
||||||
|
|
||||||
|
void emitDivRemOperation(MachineBasicBlock *BB,
|
||||||
|
MachineBasicBlock::iterator &IP,
|
||||||
|
unsigned Op0Reg, unsigned Op1Reg, bool isDiv,
|
||||||
|
const Type *Ty, unsigned TargetReg);
|
||||||
|
|
||||||
/// emitSetCCOperation - Common code shared between visitSetCondInst and
|
/// emitSetCCOperation - Common code shared between visitSetCondInst and
|
||||||
/// constant expression support.
|
/// constant expression support.
|
||||||
void emitSetCCOperation(MachineBasicBlock *BB,
|
void emitSetCCOperation(MachineBasicBlock *BB,
|
||||||
@@ -355,6 +356,22 @@ void ISel::copyConstantToRegister(MachineBasicBlock *MBB,
|
|||||||
Class, R);
|
Class, R);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case Instruction::Mul: {
|
||||||
|
unsigned Op0Reg = getReg(CE->getOperand(0), MBB, IP);
|
||||||
|
unsigned Op1Reg = getReg(CE->getOperand(1), MBB, IP);
|
||||||
|
doMultiply(MBB, IP, R, CE->getType(), Op0Reg, Op1Reg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case Instruction::Div:
|
||||||
|
case Instruction::Rem: {
|
||||||
|
unsigned Op0Reg = getReg(CE->getOperand(0), MBB, IP);
|
||||||
|
unsigned Op1Reg = getReg(CE->getOperand(1), MBB, IP);
|
||||||
|
emitDivRemOperation(MBB, IP, Op0Reg, Op1Reg,
|
||||||
|
CE->getOpcode() == Instruction::Div,
|
||||||
|
CE->getType(), R);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case Instruction::SetNE:
|
case Instruction::SetNE:
|
||||||
case Instruction::SetEQ:
|
case Instruction::SetEQ:
|
||||||
case Instruction::SetLT:
|
case Instruction::SetLT:
|
||||||
@@ -1339,21 +1356,30 @@ void ISel::visitMul(BinaryOperator &I) {
|
|||||||
/// instructions work differently for signed and unsigned operands.
|
/// instructions work differently for signed and unsigned operands.
|
||||||
///
|
///
|
||||||
void ISel::visitDivRem(BinaryOperator &I) {
|
void ISel::visitDivRem(BinaryOperator &I) {
|
||||||
unsigned Class = getClass(I.getType());
|
unsigned Op0Reg = getReg(I.getOperand(0));
|
||||||
unsigned Op0Reg, Op1Reg, ResultReg = getReg(I);
|
unsigned Op1Reg = getReg(I.getOperand(1));
|
||||||
|
unsigned ResultReg = getReg(I);
|
||||||
|
|
||||||
|
MachineBasicBlock::iterator IP = BB->end();
|
||||||
|
emitDivRemOperation(BB, IP, Op0Reg, Op1Reg, I.getOpcode() == Instruction::Div,
|
||||||
|
I.getType(), ResultReg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ISel::emitDivRemOperation(MachineBasicBlock *BB,
|
||||||
|
MachineBasicBlock::iterator &IP,
|
||||||
|
unsigned Op0Reg, unsigned Op1Reg, bool isDiv,
|
||||||
|
const Type *Ty, unsigned ResultReg) {
|
||||||
|
unsigned Class = getClass(Ty);
|
||||||
switch (Class) {
|
switch (Class) {
|
||||||
case cFP: // Floating point divide
|
case cFP: // Floating point divide
|
||||||
if (I.getOpcode() == Instruction::Div) {
|
if (isDiv) {
|
||||||
Op0Reg = getReg(I.getOperand(0));
|
|
||||||
Op1Reg = getReg(I.getOperand(1));
|
|
||||||
BuildMI(BB, X86::FpDIV, 2, ResultReg).addReg(Op0Reg).addReg(Op1Reg);
|
BuildMI(BB, X86::FpDIV, 2, ResultReg).addReg(Op0Reg).addReg(Op1Reg);
|
||||||
} else { // Floating point remainder...
|
} else { // Floating point remainder...
|
||||||
MachineInstr *TheCall =
|
MachineInstr *TheCall =
|
||||||
BuildMI(X86::CALLpcrel32, 1).addExternalSymbol("fmod", true);
|
BuildMI(X86::CALLpcrel32, 1).addExternalSymbol("fmod", true);
|
||||||
std::vector<ValueRecord> Args;
|
std::vector<ValueRecord> Args;
|
||||||
Args.push_back(ValueRecord(I.getOperand(0)));
|
Args.push_back(ValueRecord(Op0Reg, Type::DoubleTy));
|
||||||
Args.push_back(ValueRecord(I.getOperand(1)));
|
Args.push_back(ValueRecord(Op1Reg, Type::DoubleTy));
|
||||||
doCall(ValueRecord(ResultReg, Type::DoubleTy), TheCall, Args);
|
doCall(ValueRecord(ResultReg, Type::DoubleTy), TheCall, Args);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -1361,14 +1387,13 @@ void ISel::visitDivRem(BinaryOperator &I) {
|
|||||||
static const char *FnName[] =
|
static const char *FnName[] =
|
||||||
{ "__moddi3", "__divdi3", "__umoddi3", "__udivdi3" };
|
{ "__moddi3", "__divdi3", "__umoddi3", "__udivdi3" };
|
||||||
|
|
||||||
unsigned NameIdx = I.getType()->isUnsigned()*2;
|
unsigned NameIdx = Ty->isUnsigned()*2 + isDiv;
|
||||||
NameIdx += I.getOpcode() == Instruction::Div;
|
|
||||||
MachineInstr *TheCall =
|
MachineInstr *TheCall =
|
||||||
BuildMI(X86::CALLpcrel32, 1).addExternalSymbol(FnName[NameIdx], true);
|
BuildMI(X86::CALLpcrel32, 1).addExternalSymbol(FnName[NameIdx], true);
|
||||||
|
|
||||||
std::vector<ValueRecord> Args;
|
std::vector<ValueRecord> Args;
|
||||||
Args.push_back(ValueRecord(I.getOperand(0)));
|
Args.push_back(ValueRecord(Op0Reg, Type::LongTy));
|
||||||
Args.push_back(ValueRecord(I.getOperand(1)));
|
Args.push_back(ValueRecord(Op1Reg, Type::LongTy));
|
||||||
doCall(ValueRecord(ResultReg, Type::LongTy), TheCall, Args);
|
doCall(ValueRecord(ResultReg, Type::LongTy), TheCall, Args);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1388,17 +1413,16 @@ void ISel::visitDivRem(BinaryOperator &I) {
|
|||||||
{ X86::IDIVr8, X86::IDIVr16, X86::IDIVr32, 0 }, // Signed division
|
{ X86::IDIVr8, X86::IDIVr16, X86::IDIVr32, 0 }, // Signed division
|
||||||
};
|
};
|
||||||
|
|
||||||
bool isSigned = I.getType()->isSigned();
|
bool isSigned = Ty->isSigned();
|
||||||
unsigned Reg = Regs[Class];
|
unsigned Reg = Regs[Class];
|
||||||
unsigned ExtReg = ExtRegs[Class];
|
unsigned ExtReg = ExtRegs[Class];
|
||||||
|
|
||||||
// Put the first operand into one of the A registers...
|
// Put the first operand into one of the A registers...
|
||||||
Op0Reg = getReg(I.getOperand(0));
|
|
||||||
BuildMI(BB, MovOpcode[Class], 1, Reg).addReg(Op0Reg);
|
BuildMI(BB, MovOpcode[Class], 1, Reg).addReg(Op0Reg);
|
||||||
|
|
||||||
if (isSigned) {
|
if (isSigned) {
|
||||||
// Emit a sign extension instruction...
|
// Emit a sign extension instruction...
|
||||||
unsigned ShiftResult = makeAnotherReg(I.getType());
|
unsigned ShiftResult = makeAnotherReg(Ty);
|
||||||
BuildMI(BB, SarOpcode[Class], 2, ShiftResult).addReg(Op0Reg).addZImm(31);
|
BuildMI(BB, SarOpcode[Class], 2, ShiftResult).addReg(Op0Reg).addZImm(31);
|
||||||
BuildMI(BB, MovOpcode[Class], 1, ExtReg).addReg(ShiftResult);
|
BuildMI(BB, MovOpcode[Class], 1, ExtReg).addReg(ShiftResult);
|
||||||
} else {
|
} else {
|
||||||
@@ -1407,11 +1431,10 @@ void ISel::visitDivRem(BinaryOperator &I) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Emit the appropriate divide or remainder instruction...
|
// Emit the appropriate divide or remainder instruction...
|
||||||
Op1Reg = getReg(I.getOperand(1));
|
|
||||||
BuildMI(BB, DivOpcode[isSigned][Class], 1).addReg(Op1Reg);
|
BuildMI(BB, DivOpcode[isSigned][Class], 1).addReg(Op1Reg);
|
||||||
|
|
||||||
// Figure out which register we want to pick the result out of...
|
// Figure out which register we want to pick the result out of...
|
||||||
unsigned DestReg = (I.getOpcode() == Instruction::Div) ? Reg : ExtReg;
|
unsigned DestReg = isDiv ? Reg : ExtReg;
|
||||||
|
|
||||||
// Put the result into the destination register...
|
// Put the result into the destination register...
|
||||||
BuildMI(BB, MovOpcode[Class], 1, ResultReg).addReg(DestReg);
|
BuildMI(BB, MovOpcode[Class], 1, ResultReg).addReg(DestReg);
|
||||||
@@ -1544,35 +1567,6 @@ void ISel::visitShiftInst(ShiftInst &I) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// EmitByteSwap - Byteswap SrcReg into DestReg.
|
|
||||||
///
|
|
||||||
void ISel::EmitByteSwap(unsigned DestReg, unsigned SrcReg, unsigned Class) {
|
|
||||||
// Emit the byte swap instruction...
|
|
||||||
switch (Class) {
|
|
||||||
case cByte:
|
|
||||||
// No byteswap necessary for 8 bit value...
|
|
||||||
BuildMI(BB, X86::MOVrr8, 1, DestReg).addReg(SrcReg);
|
|
||||||
break;
|
|
||||||
case cInt:
|
|
||||||
// Use the 32 bit bswap instruction to do a 32 bit swap...
|
|
||||||
BuildMI(BB, X86::BSWAPr32, 1, DestReg).addReg(SrcReg);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case cShort:
|
|
||||||
// For 16 bit we have to use an xchg instruction, because there is no
|
|
||||||
// 16-bit bswap. XCHG is necessarily not in SSA form, so we force things
|
|
||||||
// into AX to do the xchg.
|
|
||||||
//
|
|
||||||
BuildMI(BB, X86::MOVrr16, 1, X86::AX).addReg(SrcReg);
|
|
||||||
BuildMI(BB, X86::XCHGrr8, 2).addReg(X86::AL, MOTy::UseAndDef)
|
|
||||||
.addReg(X86::AH, MOTy::UseAndDef);
|
|
||||||
BuildMI(BB, X86::MOVrr16, 1, DestReg).addReg(X86::AX);
|
|
||||||
break;
|
|
||||||
default: assert(0 && "Cannot byteswap this class!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// visitLoadInst - Implement LLVM load instructions in terms of the x86 'mov'
|
/// visitLoadInst - Implement LLVM load instructions in terms of the x86 'mov'
|
||||||
/// instruction. The load and store instructions are the only place where we
|
/// instruction. The load and store instructions are the only place where we
|
||||||
/// need to worry about the memory layout of the target machine.
|
/// need to worry about the memory layout of the target machine.
|
||||||
|
Reference in New Issue
Block a user