mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-23 01:24:30 +00:00
There are some Mips instructions that are lowered by the
assembler such as shifts greater than 32. In the case of direct object, the code gen needs to do this lowering since the assembler is not involved. With the advent of the llvm-mc assembler, it also needs to do the same lowering. This patch makes that specific lowering code accessible to both the direct object output and the assembler. This patch does not affect generated output. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163287 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -160,71 +160,3 @@ void MipsMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
|
||||
}
|
||||
}
|
||||
|
||||
// If the D<shift> instruction has a shift amount that is greater
|
||||
// than 31 (checked in calling routine), lower it to a D<shift>32 instruction
|
||||
void MipsMCInstLower::LowerLargeShift(const MachineInstr *MI,
|
||||
MCInst& Inst,
|
||||
int64_t Shift) {
|
||||
// rt
|
||||
Inst.addOperand(LowerOperand(MI->getOperand(0)));
|
||||
// rd
|
||||
Inst.addOperand(LowerOperand(MI->getOperand(1)));
|
||||
// saminus32
|
||||
Inst.addOperand(MCOperand::CreateImm(Shift));
|
||||
|
||||
switch (MI->getOpcode()) {
|
||||
default:
|
||||
// Calling function is not synchronized
|
||||
llvm_unreachable("Unexpected shift instruction");
|
||||
break;
|
||||
case Mips::DSLL:
|
||||
Inst.setOpcode(Mips::DSLL32);
|
||||
break;
|
||||
case Mips::DSRL:
|
||||
Inst.setOpcode(Mips::DSRL32);
|
||||
break;
|
||||
case Mips::DSRA:
|
||||
Inst.setOpcode(Mips::DSRA32);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Pick a DEXT or DINS instruction variant based on the pos and size operands
|
||||
void MipsMCInstLower::LowerDextDins(const MachineInstr *MI, MCInst& Inst) {
|
||||
int Opcode = MI->getOpcode();
|
||||
|
||||
if (Opcode == Mips::DEXT)
|
||||
assert(MI->getNumOperands() == 4 &&
|
||||
"Invalid no. of machine operands for DEXT!");
|
||||
else // Only DEXT and DINS are possible
|
||||
assert(MI->getNumOperands() == 5 &&
|
||||
"Invalid no. of machine operands for DINS!");
|
||||
|
||||
assert(MI->getOperand(2).isImm());
|
||||
int64_t pos = MI->getOperand(2).getImm();
|
||||
assert(MI->getOperand(3).isImm());
|
||||
int64_t size = MI->getOperand(3).getImm();
|
||||
|
||||
// rt
|
||||
Inst.addOperand(LowerOperand(MI->getOperand(0)));
|
||||
// rs
|
||||
Inst.addOperand(LowerOperand(MI->getOperand(1)));
|
||||
|
||||
if (size <= 32) {
|
||||
if ((pos < 32)) { // DEXT/DINS
|
||||
Inst.addOperand(MCOperand::CreateImm(pos));
|
||||
Inst.addOperand(MCOperand::CreateImm(size));
|
||||
Inst.setOpcode(Opcode);
|
||||
} else { // DEXTU/DINSU
|
||||
Inst.addOperand(MCOperand::CreateImm(pos - 32));
|
||||
Inst.addOperand(MCOperand::CreateImm(size));
|
||||
Inst.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTU : Mips::DINSU);
|
||||
}
|
||||
} else { // DEXTM/DINSM
|
||||
assert(pos < 32 && "DEXT/DINS cannot have both size and pos > 32");
|
||||
Inst.addOperand(MCOperand::CreateImm(pos));
|
||||
Inst.addOperand(MCOperand::CreateImm(size - 32));
|
||||
Inst.setOpcode(Mips::DEXTM);
|
||||
Inst.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTM : Mips::DINSM);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user