diff options
| author | Evan Cheng <evan.cheng@apple.com> | 2008-11-05 18:35:52 +0000 |
|---|---|---|
| committer | Evan Cheng <evan.cheng@apple.com> | 2008-11-05 18:35:52 +0000 |
| commit | 81889d010cdb9b40e19dcffc059dc96b7d0c26d5 (patch) | |
| tree | 175e1b01ac489405f76d2f97342b83695c110583 /llvm/lib/Target/ARM/ARMCodeEmitter.cpp | |
| parent | ce2417f4e15bdd8aa3b0a7980a28b7a5937c9976 (diff) | |
| download | bcm5719-llvm-81889d010cdb9b40e19dcffc059dc96b7d0c26d5.tar.gz bcm5719-llvm-81889d010cdb9b40e19dcffc059dc96b7d0c26d5.zip | |
Restructure ARM code emitter to use instruction formats instead of addressing modes to determine how to encode instructions.
llvm-svn: 58764
Diffstat (limited to 'llvm/lib/Target/ARM/ARMCodeEmitter.cpp')
| -rw-r--r-- | llvm/lib/Target/ARM/ARMCodeEmitter.cpp | 260 |
1 files changed, 136 insertions, 124 deletions
diff --git a/llvm/lib/Target/ARM/ARMCodeEmitter.cpp b/llvm/lib/Target/ARM/ARMCodeEmitter.cpp index 47aa22b7d9d..193df988dc1 100644 --- a/llvm/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/llvm/lib/Target/ARM/ARMCodeEmitter.cpp @@ -69,10 +69,6 @@ namespace { 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 @@ namespace { 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); - - /// getInstrBinary - Return binary encoding for the specified - /// machine instruction. - unsigned getInstrBinary(const MachineInstr &MI); + void emitDataProcessingInstruction(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 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) { 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 @@ void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) { 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 @@ unsigned ARMCodeEmitter::getAddrModeSBit(const MachineInstr &MI, 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 @@ unsigned ARMCodeEmitter::getAddrMode1InstrBinary(const MachineInstr &MI, } // 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 @@ unsigned ARMCodeEmitter::getAddrMode1InstrBinary(const MachineInstr &MI, } // 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 @@ unsigned ARMCodeEmitter::getAddrMode2InstrBinary(const MachineInstr &MI, 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 @@ unsigned ARMCodeEmitter::getAddrMode2InstrBinary(const MachineInstr &MI, 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 @@ unsigned ARMCodeEmitter::getAddrMode3InstrBinary(const MachineInstr &MI, // 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 @@ unsigned ARMCodeEmitter::getAddrMode3InstrBinary(const MachineInstr &MI, 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 @@ unsigned ARMCodeEmitter::getAddrMode4InstrBinary(const MachineInstr &MI, 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 @@ unsigned ARMCodeEmitter::getAddrMode6InstrBinary(const MachineInstr &MI, // 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" |

