Restructure ARM code emitter to use instruction formats instead of addressing modes to determine how to encode instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58764 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp
index 47aa22b..193df98 100644
--- a/lib/Target/ARM/ARMCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMCodeEmitter.cpp
@@ -69,10 +69,6 @@
void emitPseudoInstruction(const MachineInstr &MI);
- unsigned getAddrModeNoneInstrBinary(const MachineInstr &MI,
- const TargetInstrDesc &TID,
- unsigned Binary);
-
unsigned getMachineSoRegOpValue(const MachineInstr &MI,
const TargetInstrDesc &TID,
const MachineOperand &MO,
@@ -85,25 +81,19 @@
unsigned getAddrModeSBit(const MachineInstr &MI,
const TargetInstrDesc &TID) const;
- unsigned getAddrMode1InstrBinary(const MachineInstr &MI,
- const TargetInstrDesc &TID,
- unsigned Binary);
- unsigned getAddrMode2InstrBinary(const MachineInstr &MI,
- const TargetInstrDesc &TID,
- unsigned Binary);
- unsigned getAddrMode3InstrBinary(const MachineInstr &MI,
- const TargetInstrDesc &TID,
- unsigned Binary);
- unsigned getAddrMode4InstrBinary(const MachineInstr &MI,
- const TargetInstrDesc &TID,
- unsigned Binary);
- unsigned getAddrMode6InstrBinary(const MachineInstr &MI,
- const TargetInstrDesc &TID,
- unsigned Binary);
+ void emitDataProcessingInstruction(const MachineInstr &MI);
- /// getInstrBinary - Return binary encoding for the specified
- /// machine instruction.
- unsigned getInstrBinary(const MachineInstr &MI);
+ void emitLoadStoreInstruction(const MachineInstr &MI);
+
+ void emitMiscLoadStoreInstruction(const MachineInstr &MI);
+
+ void emitLoadStoreMultipleInstruction(const MachineInstr &MI);
+
+ void emitMulFrm1Instruction(const MachineInstr &MI);
+
+ void emitBranchInstruction(const MachineInstr &MI);
+
+ void emitMiscBranchInstruction(const MachineInstr &MI);
/// getBinaryCodeForInstr - This function, generated by the
/// CodeEmitterGenerator using TableGen, produces the binary encoding for
@@ -260,10 +250,39 @@
DOUT << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << MI;
NumEmitted++; // Keep track of the # of mi's emitted
- if ((MI.getDesc().TSFlags & ARMII::FormMask) == ARMII::Pseudo)
+ switch (MI.getDesc().TSFlags & ARMII::FormMask) {
+ default:
+ assert(0 && "Unhandled instruction encoding format!");
+ break;
+ case ARMII::Pseudo:
emitPseudoInstruction(MI);
- else
- MCE.emitWordLE(getInstrBinary(MI));
+ break;
+ case ARMII::DPFrm:
+ case ARMII::DPSoRegFrm:
+ emitDataProcessingInstruction(MI);
+ break;
+ case ARMII::LdFrm:
+ case ARMII::StFrm:
+ emitLoadStoreInstruction(MI);
+ break;
+ case ARMII::LdMiscFrm:
+ case ARMII::StMiscFrm:
+ emitMiscLoadStoreInstruction(MI);
+ break;
+ case ARMII::LdMulFrm:
+ case ARMII::StMulFrm:
+ emitLoadStoreMultipleInstruction(MI);
+ break;
+ case ARMII::MulFrm1:
+ emitMulFrm1Instruction(MI);
+ break;
+ case ARMII::Branch:
+ emitBranchInstruction(MI);
+ break;
+ case ARMII::BranchMisc:
+ emitMiscBranchInstruction(MI);
+ break;
+ }
}
void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) {
@@ -329,51 +348,13 @@
JTI->addPCLabelAddr(MO2.getImm(), MCE.getCurrentPCValue());
// PICADD is just an add instruction that implicitly read pc.
- unsigned Binary = getBinaryCodeForInstr(MI);
- const TargetInstrDesc &TID = MI.getDesc();
- MCE.emitWordLE(getAddrMode1InstrBinary(MI, TID, Binary));
+ emitDataProcessingInstruction(MI);
break;
}
}
}
-unsigned ARMCodeEmitter::getAddrModeNoneInstrBinary(const MachineInstr &MI,
- const TargetInstrDesc &TID,
- unsigned Binary) {
- // Set the conditional execution predicate
- Binary |= II->getPredicate(&MI) << 28;
-
- switch (TID.TSFlags & ARMII::FormMask) {
- default:
- assert(0 && "Unknown instruction subtype!");
- break;
- case ARMII::Branch: {
- // Set signed_immed_24 field
- Binary |= getMachineOpValue(MI, 0);
-
- // if it is a conditional branch, set cond field
- if (TID.Opcode == ARM::Bcc) {
- Binary &= 0x0FFFFFFF; // clear conditional field
- Binary |= getMachineOpValue(MI, 1) << 28; // set conditional field
- }
- break;
- }
- case ARMII::BranchMisc: {
- if (TID.Opcode == ARM::BX)
- abort(); // FIXME
- if (TID.Opcode == ARM::BX_RET)
- Binary |= 0xe; // the return register is LR
- else
- // otherwise, set the return register
- Binary |= getMachineOpValue(MI, 0);
- break;
- }
- }
-
- return Binary;
-}
-
unsigned ARMCodeEmitter::getMachineSoRegOpValue(const MachineInstr &MI,
const TargetInstrDesc &TID,
const MachineOperand &MO,
@@ -453,9 +434,14 @@
return 0;
}
-unsigned ARMCodeEmitter::getAddrMode1InstrBinary(const MachineInstr &MI,
- const TargetInstrDesc &TID,
- unsigned Binary) {
+void ARMCodeEmitter::emitDataProcessingInstruction(const MachineInstr &MI) {
+ const TargetInstrDesc &TID = MI.getDesc();
+ if (TID.getOpcode() == ARM::MOVi2pieces)
+ abort(); // FIXME
+
+ // Part of binary is determined by TableGn.
+ unsigned Binary = getBinaryCodeForInstr(MI);
+
// Set the conditional execution predicate
Binary |= II->getPredicate(&MI) << 28;
@@ -471,16 +457,12 @@
}
// Encode first non-shifter register operand if there is one.
- unsigned Format = TID.TSFlags & ARMII::FormMask;
- bool HasRnReg = !(Format == ARMII::DPRdMisc ||
- Format == ARMII::DPRdIm ||
- Format == ARMII::DPRdReg ||
- Format == ARMII::DPRdSoReg);
- if (HasRnReg) {
+ bool isUnary = TID.TSFlags & ARMII::UnaryDP;
+ if (!isUnary) {
if (TID.getOpcode() == ARM::PICADD)
- // Special handling for PICADD. It implicitly use add.
- Binary |=
- ARMRegisterInfo::getRegisterNumbering(ARM::PC) << ARMII::RegRnShift;
+ // Special handling for PICADD. It implicitly uses PC register.
+ Binary |= (ARMRegisterInfo::getRegisterNumbering(ARM::PC)
+ << ARMII::RegRnShift);
else {
Binary |= getMachineOpValue(MI, OpIdx) << ARMII::RegRnShift;
++OpIdx;
@@ -488,30 +470,33 @@
}
// Encode shifter operand.
- bool HasSoReg = (Format == ARMII::DPRdSoReg ||
- Format == ARMII::DPRnSoReg ||
- Format == ARMII::DPRSoReg ||
- Format == ARMII::DPRSoRegS);
-
const MachineOperand &MO = MI.getOperand(OpIdx);
- if (HasSoReg)
+ if ((TID.TSFlags & ARMII::FormMask) == ARMII::DPSoRegFrm) {
// Encode SoReg.
- return Binary | getMachineSoRegOpValue(MI, TID, MO, OpIdx);
+ MCE.emitWordLE(Binary | getMachineSoRegOpValue(MI, TID, MO, OpIdx));
+ return;
+ }
- if (MO.isReg())
+ if (MO.isReg()) {
// Encode register Rm.
- return Binary | ARMRegisterInfo::getRegisterNumbering(MO.getReg());
+ MCE.emitWordLE(Binary | ARMRegisterInfo::getRegisterNumbering(MO.getReg()));
+ return;
+ }
// Encode so_imm.
// Set bit I(25) to identify this is the immediate form of <shifter_op>
Binary |= 1 << ARMII::I_BitShift;
Binary |= getMachineSoImmOpValue(MI, TID, MO);
- return Binary;
+
+ MCE.emitWordLE(Binary);
}
-unsigned ARMCodeEmitter::getAddrMode2InstrBinary(const MachineInstr &MI,
- const TargetInstrDesc &TID,
- unsigned Binary) {
+void ARMCodeEmitter::emitLoadStoreInstruction(const MachineInstr &MI) {
+ const TargetInstrDesc &TID = MI.getDesc();
+
+ // Part of binary is determined by TableGn.
+ unsigned Binary = getBinaryCodeForInstr(MI);
+
// Set the conditional execution predicate
Binary |= II->getPredicate(&MI) << 28;
@@ -531,7 +516,8 @@
if (ARM_AM::getAM2Offset(MO3.getImm()))
// Set the value of offset_12 field
Binary |= ARM_AM::getAM2Offset(MO3.getImm());
- return Binary;
+ MCE.emitWordLE(Binary);
+ return;
}
// Set bit I(25), because this is not in immediate enconding.
@@ -547,12 +533,15 @@
Binary |= ShImm << 7; // shift_immed
}
- return Binary;
+ MCE.emitWordLE(Binary);
}
-unsigned ARMCodeEmitter::getAddrMode3InstrBinary(const MachineInstr &MI,
- const TargetInstrDesc &TID,
- unsigned Binary) {
+void ARMCodeEmitter::emitMiscLoadStoreInstruction(const MachineInstr &MI) {
+ const TargetInstrDesc &TID = MI.getDesc();
+
+ // Part of binary is determined by TableGn.
+ unsigned Binary = getBinaryCodeForInstr(MI);
+
// Set the conditional execution predicate
Binary |= II->getPredicate(&MI) << 28;
@@ -573,7 +562,8 @@
// to the corresponding Rm register.
if (MO2.getReg()) {
Binary |= ARMRegisterInfo::getRegisterNumbering(MO2.getReg());
- return Binary;
+ MCE.emitWordLE(Binary);
+ return;
}
// if this instr is in immediate offset/index encoding, set bit 22 to 1
@@ -584,12 +574,15 @@
Binary |= (ImmOffs & ~0xF); // immedL
}
- return Binary;
+ MCE.emitWordLE(Binary);
}
-unsigned ARMCodeEmitter::getAddrMode4InstrBinary(const MachineInstr &MI,
- const TargetInstrDesc &TID,
- unsigned Binary) {
+void ARMCodeEmitter::emitLoadStoreMultipleInstruction(const MachineInstr &MI) {
+ const TargetInstrDesc &TID = MI.getDesc();
+
+ // Part of binary is determined by TableGn.
+ unsigned Binary = getBinaryCodeForInstr(MI);
+
// Set the conditional execution predicate
Binary |= II->getPredicate(&MI) << 28;
@@ -626,12 +619,15 @@
Binary |= 0x1 << RegNum;
}
- return Binary;
+ MCE.emitWordLE(Binary);
}
-unsigned ARMCodeEmitter::getAddrMode6InstrBinary(const MachineInstr &MI,
- const TargetInstrDesc &TID,
- unsigned Binary) {
+void ARMCodeEmitter::emitMulFrm1Instruction(const MachineInstr &MI) {
+ const TargetInstrDesc &TID = MI.getDesc();
+
+ // Part of binary is determined by TableGn.
+ unsigned Binary = getBinaryCodeForInstr(MI);
+
// Set the conditional execution predicate
Binary |= II->getPredicate(&MI) << 28;
@@ -653,33 +649,49 @@
// Encode Rs
Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRsShift;
- return Binary;
+ MCE.emitWordLE(Binary);
}
-/// getInstrBinary - Return binary encoding for the specified
-/// machine instruction.
-unsigned ARMCodeEmitter::getInstrBinary(const MachineInstr &MI) {
+void ARMCodeEmitter::emitBranchInstruction(const MachineInstr &MI) {
+ const TargetInstrDesc &TID = MI.getDesc();
+
// Part of binary is determined by TableGn.
unsigned Binary = getBinaryCodeForInstr(MI);
- const TargetInstrDesc &TID = MI.getDesc();
- switch (TID.TSFlags & ARMII::AddrModeMask) {
- case ARMII::AddrModeNone:
- return getAddrModeNoneInstrBinary(MI, TID, Binary);
- case ARMII::AddrMode1:
- return getAddrMode1InstrBinary(MI, TID, Binary);
- case ARMII::AddrMode2:
- return getAddrMode2InstrBinary(MI, TID, Binary);
- case ARMII::AddrMode3:
- return getAddrMode3InstrBinary(MI, TID, Binary);
- case ARMII::AddrMode4:
- return getAddrMode4InstrBinary(MI, TID, Binary);
- case ARMII::AddrMode6:
- return getAddrMode6InstrBinary(MI, TID, Binary);
+ // Set the conditional execution predicate
+ Binary |= II->getPredicate(&MI) << 28;
+
+ // Set signed_immed_24 field
+ Binary |= getMachineOpValue(MI, 0);
+
+ // if it is a conditional branch, set cond field
+ if (TID.Opcode == ARM::Bcc) {
+ Binary &= 0x0FFFFFFF; // clear conditional field
+ Binary |= getMachineOpValue(MI, 1) << 28; // set conditional field
}
- abort();
- return 0;
+ MCE.emitWordLE(Binary);
+}
+
+void ARMCodeEmitter::emitMiscBranchInstruction(const MachineInstr &MI) {
+ const TargetInstrDesc &TID = MI.getDesc();
+ if (TID.Opcode == ARM::BX)
+ abort(); // FIXME
+
+ // Part of binary is determined by TableGn.
+ unsigned Binary = getBinaryCodeForInstr(MI);
+
+ // Set the conditional execution predicate
+ Binary |= II->getPredicate(&MI) << 28;
+
+ if (TID.Opcode == ARM::BX_RET)
+ // The return register is LR.
+ Binary |= ARMRegisterInfo::getRegisterNumbering(ARM::LR);
+ else
+ // otherwise, set the return register
+ Binary |= getMachineOpValue(MI, 0);
+
+ MCE.emitWordLE(Binary);
}
#include "ARMGenCodeEmitter.inc"