diff options
| author | Bob Wilson <bob.wilson@apple.com> | 2010-06-11 21:34:50 +0000 |
|---|---|---|
| committer | Bob Wilson <bob.wilson@apple.com> | 2010-06-11 21:34:50 +0000 |
| commit | 6eae520de934f6e3aa60e976e3efa37fa7a39a72 (patch) | |
| tree | 98347f2c4c9386ff1d807b8de71ae65b2731de8c /llvm/lib/Target/ARM/AsmPrinter | |
| parent | 571e864e84fd580a0a0b6281d4b49c6999dcab48 (diff) | |
| download | bcm5719-llvm-6eae520de934f6e3aa60e976e3efa37fa7a39a72.tar.gz bcm5719-llvm-6eae520de934f6e3aa60e976e3efa37fa7a39a72.zip | |
Add instruction encoding for the Neon VMOV immediate instruction. This changes
the machine instruction representation of the immediate value to be encoded
into an integer with similar fields as the actual VMOV instruction. This makes
things easier for the disassembler, since it can just stuff the bits into the
immediate operand, but harder for the asm printer since it has to decode the
value to be printed. Testcase for the encoding will follow later when MC has
more support for ARM.
llvm-svn: 105836
Diffstat (limited to 'llvm/lib/Target/ARM/AsmPrinter')
| -rw-r--r-- | llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp | 53 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp | 50 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h | 5 |
3 files changed, 69 insertions, 39 deletions
diff --git a/llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp index a5a28692f11..e1246153114 100644 --- a/llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp +++ b/llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp @@ -175,23 +175,8 @@ namespace { raw_ostream &O); void printVFPf64ImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O); - - void printHex8ImmOperand(const MachineInstr *MI, int OpNum, - raw_ostream &O) { - O << "#0x" << utohexstr(MI->getOperand(OpNum).getImm() & 0xff); - } - void printHex16ImmOperand(const MachineInstr *MI, int OpNum, - raw_ostream &O) { - O << "#0x" << utohexstr(MI->getOperand(OpNum).getImm() & 0xffff); - } - void printHex32ImmOperand(const MachineInstr *MI, int OpNum, - raw_ostream &O) { - O << "#0x" << utohexstr(MI->getOperand(OpNum).getImm() & 0xffffffff); - } - void printHex64ImmOperand(const MachineInstr *MI, int OpNum, - raw_ostream &O) { - O << "#0x" << utohexstr(MI->getOperand(OpNum).getImm()); - } + void printNEONModImmOperand(const MachineInstr *MI, int OpNum, + raw_ostream &O); virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, unsigned AsmVariant, const char *ExtraCode, @@ -1039,6 +1024,40 @@ void ARMAsmPrinter::printVFPf64ImmOperand(const MachineInstr *MI, int OpNum, } } +void ARMAsmPrinter::printNEONModImmOperand(const MachineInstr *MI, int OpNum, + raw_ostream &O) { + unsigned Imm = MI->getOperand(OpNum).getImm(); + unsigned OpCmode = (Imm >> 8) & 0x1f; + unsigned Imm8 = Imm & 0xff; + uint64_t Val = 0; + + if (OpCmode == 0xe) { + // 8-bit vector elements + Val = Imm8; + } else if ((OpCmode & 0xc) == 0x8) { + // 16-bit vector elements + unsigned ByteNum = (OpCmode & 0x6) >> 1; + Val = Imm8 << (8 * ByteNum); + } else if ((OpCmode & 0x8) == 0) { + // 32-bit vector elements, zero with one byte set + unsigned ByteNum = (OpCmode & 0x6) >> 1; + Val = Imm8 << (8 * ByteNum); + } else if ((OpCmode & 0xe) == 0xc) { + // 32-bit vector elements, one byte with low bits set + unsigned ByteNum = (OpCmode & 0x1); + Val = (Imm8 << (8 * ByteNum)) | (0xffff >> (8 * (1 - ByteNum))); + } else if (OpCmode == 0x1e) { + // 64-bit vector elements + for (unsigned ByteNum = 0; ByteNum < 8; ++ByteNum) { + if ((Imm >> ByteNum) & 1) + Val |= (uint64_t)0xff << (8 * ByteNum); + } + } else { + assert(false && "Unsupported NEON immediate"); + } + O << "#0x" << utohexstr(Val); +} + bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, unsigned AsmVariant, const char *ExtraCode, raw_ostream &O) { diff --git a/llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp b/llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp index 2b94b76087e..b59852ebfcb 100644 --- a/llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp +++ b/llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp @@ -779,22 +779,36 @@ void ARMInstPrinter::printVFPf64ImmOperand(const MCInst *MI, unsigned OpNum, O << '#' << MI->getOperand(OpNum).getImm(); } -void ARMInstPrinter::printHex8ImmOperand(const MCInst *MI, unsigned OpNum, - raw_ostream &O) { - O << "#0x" << utohexstr(MI->getOperand(OpNum).getImm() & 0xff); -} - -void ARMInstPrinter::printHex16ImmOperand(const MCInst *MI, unsigned OpNum, - raw_ostream &O) { - O << "#0x" << utohexstr(MI->getOperand(OpNum).getImm() & 0xffff); -} - -void ARMInstPrinter::printHex32ImmOperand(const MCInst *MI, unsigned OpNum, - raw_ostream &O) { - O << "#0x" << utohexstr(MI->getOperand(OpNum).getImm() & 0xffffffff); -} - -void ARMInstPrinter::printHex64ImmOperand(const MCInst *MI, unsigned OpNum, - raw_ostream &O) { - O << "#0x" << utohexstr(MI->getOperand(OpNum).getImm()); +void ARMInstPrinter::printNEONModImmOperand(const MCInst *MI, unsigned OpNum, + raw_ostream &O) { + unsigned Imm = MI->getOperand(OpNum).getImm(); + unsigned OpCmode = (Imm >> 8) & 0x1f; + unsigned Imm8 = Imm & 0xff; + uint64_t Val = 0; + + if (OpCmode == 0xe) { + // 8-bit vector elements + Val = Imm8; + } else if ((OpCmode & 0xc) == 0x8) { + // 16-bit vector elements + unsigned ByteNum = (OpCmode & 0x6) >> 1; + Val = Imm8 << (8 * ByteNum); + } else if ((OpCmode & 0x8) == 0) { + // 32-bit vector elements, zero with one byte set + unsigned ByteNum = (OpCmode & 0x6) >> 1; + Val = Imm8 << (8 * ByteNum); + } else if ((OpCmode & 0xe) == 0xc) { + // 32-bit vector elements, one byte with low bits set + unsigned ByteNum = (OpCmode & 0x1); + Val = (Imm8 << (8 * ByteNum)) | (0xffff >> (8 * (1 - ByteNum))); + } else if (OpCmode == 0x1e) { + // 64-bit vector elements + for (unsigned ByteNum = 0; ByteNum < 8; ++ByteNum) { + if ((Imm >> ByteNum) & 1) + Val |= (uint64_t)0xff << (8 * ByteNum); + } + } else { + assert(false && "Unsupported NEON immediate"); + } + O << "#0x" << utohexstr(Val); } diff --git a/llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h b/llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h index be0b7c1eb02..ddf5047793d 100644 --- a/llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h +++ b/llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h @@ -104,10 +104,7 @@ public: void printNoHashImmediate(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printVFPf32ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printVFPf64ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printHex8ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printHex16ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printHex32ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printHex64ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); + void printNEONModImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printPCLabel(const MCInst *MI, unsigned OpNum, raw_ostream &O); // FIXME: Implement. |

