[ARM64] Register-offset loads and stores with the 'option' field equal to 00x or 10x are undefined.

llvm-svn: 205858
This commit is contained in:
Bradley Smith 2014-04-09 14:41:38 +00:00
parent 2c4e8ae0fd
commit cd91e5cd0c
2 changed files with 12 additions and 14 deletions

View File

@ -1262,70 +1262,61 @@ static DecodeStatus DecodeRegOffsetLdStInstruction(llvm::MCInst &Inst,
unsigned Rm = fieldFromInstruction(insn, 16, 5); unsigned Rm = fieldFromInstruction(insn, 16, 5);
unsigned extendHi = fieldFromInstruction(insn, 13, 3); unsigned extendHi = fieldFromInstruction(insn, 13, 3);
unsigned extendLo = fieldFromInstruction(insn, 12, 1); unsigned extendLo = fieldFromInstruction(insn, 12, 1);
unsigned extend = 0; unsigned extend = (extendHi << 1) | extendLo;
// All RO load-store instructions are undefined if option == 00x or 10x.
if (extend >> 2 == 0x0 || extend >> 2 == 0x2)
return Fail;
switch (Inst.getOpcode()) { switch (Inst.getOpcode()) {
default: default:
return Fail; return Fail;
case ARM64::LDRSWro: case ARM64::LDRSWro:
extend = (extendHi << 1) | extendLo;
DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
break; break;
case ARM64::LDRXro: case ARM64::LDRXro:
case ARM64::STRXro: case ARM64::STRXro:
extend = (extendHi << 1) | extendLo;
DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
break; break;
case ARM64::LDRWro: case ARM64::LDRWro:
case ARM64::STRWro: case ARM64::STRWro:
extend = (extendHi << 1) | extendLo;
DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
break; break;
case ARM64::LDRQro: case ARM64::LDRQro:
case ARM64::STRQro: case ARM64::STRQro:
extend = (extendHi << 1) | extendLo;
DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder); DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
break; break;
case ARM64::LDRDro: case ARM64::LDRDro:
case ARM64::STRDro: case ARM64::STRDro:
extend = (extendHi << 1) | extendLo;
DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder); DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
break; break;
case ARM64::LDRSro: case ARM64::LDRSro:
case ARM64::STRSro: case ARM64::STRSro:
extend = (extendHi << 1) | extendLo;
DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder); DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
break; break;
case ARM64::LDRHro: case ARM64::LDRHro:
extend = (extendHi << 1) | extendLo;
DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder); DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder);
break; break;
case ARM64::LDRBro: case ARM64::LDRBro:
extend = (extendHi << 1) | extendLo;
DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder); DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder);
break; break;
case ARM64::LDRBBro: case ARM64::LDRBBro:
case ARM64::STRBBro: case ARM64::STRBBro:
case ARM64::LDRSBWro: case ARM64::LDRSBWro:
extend = (extendHi << 1) | extendLo;
DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
break; break;
case ARM64::LDRHHro: case ARM64::LDRHHro:
case ARM64::STRHHro: case ARM64::STRHHro:
case ARM64::LDRSHWro: case ARM64::LDRSHWro:
extend = (extendHi << 1) | extendLo;
DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
break; break;
case ARM64::LDRSHXro: case ARM64::LDRSHXro:
extend = (extendHi << 1) | extendLo;
DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
break; break;
case ARM64::LDRSBXro: case ARM64::LDRSBXro:
extend = (extendHi << 1) | extendLo;
DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
break; break;
case ARM64::PRFMro: case ARM64::PRFMro:
extend = (extendHi << 1) | extendLo;
Inst.addOperand(MCOperand::CreateImm(Rt)); Inst.addOperand(MCOperand::CreateImm(Rt));
} }

View File

@ -0,0 +1,7 @@
# These spawn another process so they're rather expensive. Not many.
# LDR/STR: undefined if option field is 10x or 00x.
# RUN: echo "0x00 0x08 0x20 0xf8" | llvm-mc -triple arm64 -disassemble 2>&1 | FileCheck %s
# RUN: echo "0x00 0x88 0x00 0xf8" | llvm-mc -triple arm64 -disassemble 2>&1 | FileCheck %s
# CHECK: invalid instruction encoding