diff options
author | Evan Cheng <evan.cheng@apple.com> | 2008-11-11 02:11:05 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2008-11-11 02:11:05 +0000 |
commit | ac2af2fdb2d7686c7ff79733604bf63772ba53b6 (patch) | |
tree | 84201b54fc787be8e0c6e4df27b557a4a803b54a /llvm/lib/Target/ARM/ARMCodeEmitter.cpp | |
parent | deb7cac332635f550153eeacbf03d05fe1e086de (diff) | |
download | bcm5719-llvm-ac2af2fdb2d7686c7ff79733604bf63772ba53b6.tar.gz bcm5719-llvm-ac2af2fdb2d7686c7ff79733604bf63772ba53b6.zip |
Encode VFP arithmetic instructions.
llvm-svn: 59016
Diffstat (limited to 'llvm/lib/Target/ARM/ARMCodeEmitter.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/ARMCodeEmitter.cpp | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMCodeEmitter.cpp b/llvm/lib/Target/ARM/ARMCodeEmitter.cpp index ddd2564d9ef..b39ab7f833d 100644 --- a/llvm/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/llvm/lib/Target/ARM/ARMCodeEmitter.cpp @@ -120,6 +120,8 @@ namespace { void emitMiscBranchInstruction(const MachineInstr &MI); + void emitVFPArithInstruction(const MachineInstr &MI); + /// getBinaryCodeForInstr - This function, generated by the /// CodeEmitterGenerator using TableGen, produces the binary encoding for /// machine instructions. @@ -313,6 +315,11 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) { case ARMII::BrMiscFrm: emitMiscBranchInstruction(MI); break; + // VFP instructions. + case ARMII::VFPUnaryFrm: + case ARMII::VFPBinaryFrm: + emitVFPArithInstruction(MI); + break; } } @@ -976,4 +983,42 @@ void ARMCodeEmitter::emitMiscBranchInstruction(const MachineInstr &MI) { emitWordLE(Binary); } +void ARMCodeEmitter::emitVFPArithInstruction(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) << ARMII::CondShift; + + unsigned OpIdx = 0; + assert((Binary & ARMII::D_BitShift) == 0 && + (Binary & ARMII::N_BitShift) == 0 && + (Binary & ARMII::M_BitShift) == 0 && "VFP encoding bug!"); + + // Encode Dd / Sd. + unsigned RegD = getMachineOpValue(MI, OpIdx++); + Binary |= (RegD & 0x0f) << ARMII::RegFdShift; + Binary |= (RegD & 0x10) << ARMII::D_BitShift; + + // If this is a two-address operand, skip it, e.g. FMACD. + if (TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1) + ++OpIdx; + + // Encode Dn / Sn. + if ((TID.TSFlags & ARMII::FormMask) == ARMII::VFPBinaryFrm) { + unsigned RegN = getMachineOpValue(MI, OpIdx++); + Binary |= (RegN & 0x0f); + Binary |= (RegN & 0x10) << ARMII::N_BitShift; + } + + // Encode Dm / Sm. + unsigned RegM = getMachineOpValue(MI, OpIdx++); + Binary |= (RegM & 0x0f); + Binary |= (RegM & 0x10) << ARMII::M_BitShift; + + emitWordLE(Binary); +} + #include "ARMGenCodeEmitter.inc" |