[MC][AVR] Implement decoding ST/LD
Reviewed By: aykevl, dylanmckay Differential Revision: https://reviews.llvm.org/D123476
This commit is contained in:
parent
cef2739d68
commit
b1dcd6bafb
|
@ -276,9 +276,11 @@ static DecodeStatus decodeMemri(MCInst &Inst, unsigned Insn, uint64_t Address,
|
|||
static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn,
|
||||
uint64_t Address,
|
||||
const MCDisassembler *Decoder) {
|
||||
// Get the register will be loaded or stored.
|
||||
unsigned RegVal = GPRDecoderTable[(Insn >> 4) & 0x1f];
|
||||
|
||||
// Decode LDD/STD with offset less than 8.
|
||||
if ((Insn & 0xf000) == 0x8000) {
|
||||
unsigned RegVal = GPRDecoderTable[(Insn >> 4) & 0x1f];
|
||||
unsigned RegBase = (Insn & 0x8) ? AVR::R29R28 : AVR::R31R30;
|
||||
unsigned Offset = Insn & 7; // We need not consider offset > 7.
|
||||
if ((Insn & 0x200) == 0) { // Decode LDD.
|
||||
|
@ -295,8 +297,85 @@ static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn,
|
|||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
// TODO: Decode ST/LD with postinc/predec properly.
|
||||
return MCDisassembler::Fail;
|
||||
// Decode the following 14 instructions. Bit 9 indicates load(0) or store(1),
|
||||
// bits 8~4 indicate the value register, bits 3-2 indicate the base address
|
||||
// register (11-X, 10-Y, 00-Z), bits 1~0 indicate the mode (00-basic,
|
||||
// 01-postinc, 10-predec).
|
||||
// ST X, Rr : 1001 001r rrrr 1100
|
||||
// ST X+, Rr : 1001 001r rrrr 1101
|
||||
// ST -X, Rr : 1001 001r rrrr 1110
|
||||
// ST Y+, Rr : 1001 001r rrrr 1001
|
||||
// ST -Y, Rr : 1001 001r rrrr 1010
|
||||
// ST Z+, Rr : 1001 001r rrrr 0001
|
||||
// ST -Z, Rr : 1001 001r rrrr 0010
|
||||
// LD Rd, X : 1001 000d dddd 1100
|
||||
// LD Rd, X+ : 1001 000d dddd 1101
|
||||
// LD Rd, -X : 1001 000d dddd 1110
|
||||
// LD Rd, Y+ : 1001 000d dddd 1001
|
||||
// LD Rd, -Y : 1001 000d dddd 1010
|
||||
// LD Rd, Z+ : 1001 000d dddd 0001
|
||||
// LD Rd, -Z : 1001 000d dddd 0010
|
||||
if ((Insn & 0xfc00) != 0x9000 || (Insn & 0xf) == 0)
|
||||
return MCDisassembler::Fail;
|
||||
|
||||
// Get the base address register.
|
||||
unsigned RegBase;
|
||||
switch (Insn & 0xc) {
|
||||
case 0xc:
|
||||
RegBase = AVR::R27R26;
|
||||
break;
|
||||
case 0x8:
|
||||
RegBase = AVR::R29R28;
|
||||
break;
|
||||
case 0x0:
|
||||
RegBase = AVR::R31R30;
|
||||
break;
|
||||
default:
|
||||
return MCDisassembler::Fail;
|
||||
}
|
||||
|
||||
// Set the opcode.
|
||||
switch (Insn & 0x203) {
|
||||
case 0x200:
|
||||
Inst.setOpcode(AVR::STPtrRr);
|
||||
Inst.addOperand(MCOperand::createReg(RegBase));
|
||||
Inst.addOperand(MCOperand::createReg(RegVal));
|
||||
return MCDisassembler::Success;
|
||||
case 0x201:
|
||||
Inst.setOpcode(AVR::STPtrPiRr);
|
||||
break;
|
||||
case 0x202:
|
||||
Inst.setOpcode(AVR::STPtrPdRr);
|
||||
break;
|
||||
case 0:
|
||||
Inst.setOpcode(AVR::LDRdPtr);
|
||||
Inst.addOperand(MCOperand::createReg(RegVal));
|
||||
Inst.addOperand(MCOperand::createReg(RegBase));
|
||||
return MCDisassembler::Success;
|
||||
case 1:
|
||||
Inst.setOpcode(AVR::LDRdPtrPi);
|
||||
break;
|
||||
case 2:
|
||||
Inst.setOpcode(AVR::LDRdPtrPd);
|
||||
break;
|
||||
default:
|
||||
return MCDisassembler::Fail;
|
||||
}
|
||||
|
||||
// Build postinc/predec machine instructions.
|
||||
if ((Insn & 0x200) == 0) { // This is a load instruction.
|
||||
Inst.addOperand(MCOperand::createReg(RegVal));
|
||||
Inst.addOperand(MCOperand::createReg(RegBase));
|
||||
Inst.addOperand(MCOperand::createReg(RegBase));
|
||||
} else { // This is a store instruction.
|
||||
Inst.addOperand(MCOperand::createReg(RegBase));
|
||||
Inst.addOperand(MCOperand::createReg(RegBase));
|
||||
Inst.addOperand(MCOperand::createReg(RegVal));
|
||||
// STPtrPiRr and STPtrPdRr have an extra immediate operand.
|
||||
Inst.addOperand(MCOperand::createImm(1));
|
||||
}
|
||||
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
|
||||
|
@ -357,7 +436,12 @@ DecodeStatus AVRDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
|
|||
// Try to auto-decode a 16-bit instruction.
|
||||
Result = decodeInstruction(getDecoderTable(Size), Instr, Insn, Address,
|
||||
this, STI);
|
||||
if (Result != MCDisassembler::Fail)
|
||||
return Result;
|
||||
|
||||
// Try to decode to a load/store instruction. ST/LD need a specified
|
||||
// DecoderMethod, as they already have a specified PostEncoderMethod.
|
||||
Result = decodeLoadStore(Instr, Insn, Address, this);
|
||||
if (Result != MCDisassembler::Fail)
|
||||
return Result;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
; RUN: llvm-mc -triple avr -mattr=sram -show-encoding < %s | FileCheck %s
|
||||
; RUN: llvm-mc -filetype=obj -triple avr -mattr=sram < %s \
|
||||
; RUN: | llvm-objdump -d --mattr=sram - | FileCheck --check-prefix=INST %s
|
||||
|
||||
|
||||
foo:
|
||||
|
@ -71,3 +73,24 @@ foo:
|
|||
|
||||
; CHECK: ld r10, -Z ; encoding: [0xa2,0x90]
|
||||
; CHECK: ld r2, -Z ; encoding: [0x22,0x90]
|
||||
|
||||
; INST: ld r10, X
|
||||
; INST: ld r17, X
|
||||
; INST: ldd r30, Y+0
|
||||
; INST: ldd r19, Y+0
|
||||
; INST: ldd r10, Z+0
|
||||
; INST: ldd r2, Z+0
|
||||
|
||||
; INST: ld r10, X+
|
||||
; INST: ld r17, X+
|
||||
; INST: ld r30, Y+
|
||||
; INST: ld r19, Y+
|
||||
; INST: ld r10, Z+
|
||||
; INST: ld r2, Z+
|
||||
|
||||
; INST: ld r10, -X
|
||||
; INST: ld r17, -X
|
||||
; INST: ld r30, -Y
|
||||
; INST: ld r19, -Y
|
||||
; INST: ld r10, -Z
|
||||
; INST: ld r2, -Z
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
; RUN: llvm-mc -triple avr -mattr=sram -show-encoding < %s | FileCheck %s
|
||||
; RUN: llvm-mc -filetype=obj -triple avr -mattr=sram < %s \
|
||||
; RUN: | llvm-objdump -d --mattr=sram - | FileCheck --check-prefix=INST %s
|
||||
|
||||
|
||||
foo:
|
||||
|
@ -69,3 +71,24 @@ foo:
|
|||
|
||||
; CHECK: st -Z, r10 ; encoding: [0xa2,0x92]
|
||||
; CHECK: st -Z, r2 ; encoding: [0x22,0x92]
|
||||
|
||||
; INST: st X, r10
|
||||
; INST: st X, r17
|
||||
; INST: std Y+0, r30
|
||||
; INST: std Y+0, r19
|
||||
; INST: std Z+0, r10
|
||||
; INST: std Z+0, r2
|
||||
|
||||
; INST: st X+, r10
|
||||
; INST: st X+, r17
|
||||
; INST: st Y+, r30
|
||||
; INST: st Y+, r19
|
||||
; INST: st Z+, r10
|
||||
; INST: st Z+, r2
|
||||
|
||||
; INST: st -X, r10
|
||||
; INST: st -X, r17
|
||||
; INST: st -Y, r30
|
||||
; INST: st -Y, r19
|
||||
; INST: st -Z, r10
|
||||
; INST: st -Z, r2
|
||||
|
|
Loading…
Reference in New Issue
Block a user