mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-27 17:31:33 +00:00
First round of fixes for the x86 fixes for the x86 move accumulator from/to memory offset instructions.
-Assembly parser now properly check the size of the memory operation specified in intel syntax. So 'mov word ptr [5], al' is no longer accepted. -x86-32 disassembly of these instructions no longer sign extends the 32-bit address immediate based on size. -Intel syntax printing prints the ptr size and places brackets around the address immediate. Known remaining issues with these instructions: -Segment override prefix is not supported. PR16962 and PR16961. -Immediate size should be changed by address size prefix. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189201 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f27c35347a
commit
a4959f3f6e
@ -849,6 +849,23 @@ struct X86Operand : public MCParsedAsmOperand {
|
||||
!getMemIndexReg() && getMemScale() == 1;
|
||||
}
|
||||
|
||||
bool isMemOffs8() const {
|
||||
return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
|
||||
!getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 8);
|
||||
}
|
||||
bool isMemOffs16() const {
|
||||
return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
|
||||
!getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 16);
|
||||
}
|
||||
bool isMemOffs32() const {
|
||||
return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
|
||||
!getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 32);
|
||||
}
|
||||
bool isMemOffs64() const {
|
||||
return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
|
||||
!getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 64);
|
||||
}
|
||||
|
||||
bool isReg() const { return Kind == Register; }
|
||||
|
||||
void addExpr(MCInst &Inst, const MCExpr *Expr) const {
|
||||
@ -931,6 +948,28 @@ struct X86Operand : public MCParsedAsmOperand {
|
||||
Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
|
||||
}
|
||||
|
||||
void addMemOffs8Operands(MCInst &Inst, unsigned N) const {
|
||||
addMemOffsOperands(Inst, N);
|
||||
}
|
||||
void addMemOffs16Operands(MCInst &Inst, unsigned N) const {
|
||||
addMemOffsOperands(Inst, N);
|
||||
}
|
||||
void addMemOffs32Operands(MCInst &Inst, unsigned N) const {
|
||||
addMemOffsOperands(Inst, N);
|
||||
}
|
||||
void addMemOffs64Operands(MCInst &Inst, unsigned N) const {
|
||||
addMemOffsOperands(Inst, N);
|
||||
}
|
||||
|
||||
void addMemOffsOperands(MCInst &Inst, unsigned N) const {
|
||||
assert((N == 1) && "Invalid number of operands!");
|
||||
// Add as immediates when possible.
|
||||
if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
|
||||
Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
|
||||
else
|
||||
Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
|
||||
}
|
||||
|
||||
static X86Operand *CreateToken(StringRef Str, SMLoc Loc) {
|
||||
SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
|
||||
X86Operand *Res = new X86Operand(Token, Loc, EndLoc);
|
||||
|
@ -231,16 +231,18 @@ static void translateImmediate(MCInst &mcInst, uint64_t immediate,
|
||||
default:
|
||||
break;
|
||||
case 1:
|
||||
type = TYPE_MOFFS8;
|
||||
if(immediate & 0x80)
|
||||
immediate |= ~(0xffull);
|
||||
break;
|
||||
case 2:
|
||||
type = TYPE_MOFFS16;
|
||||
if(immediate & 0x8000)
|
||||
immediate |= ~(0xffffull);
|
||||
break;
|
||||
case 4:
|
||||
type = TYPE_MOFFS32;
|
||||
if(immediate & 0x80000000)
|
||||
immediate |= ~(0xffffffffull);
|
||||
break;
|
||||
case 8:
|
||||
type = TYPE_MOFFS64;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -263,16 +265,18 @@ static void translateImmediate(MCInst &mcInst, uint64_t immediate,
|
||||
Opcode != X86::VMPSADBWrri && Opcode != X86::VDPPSYrri &&
|
||||
Opcode != X86::VDPPSYrmi && Opcode != X86::VDPPDrri &&
|
||||
Opcode != X86::VINSERTPSrr)
|
||||
type = TYPE_MOFFS8;
|
||||
if(immediate & 0x80)
|
||||
immediate |= ~(0xffull);
|
||||
break;
|
||||
case ENCODING_IW:
|
||||
type = TYPE_MOFFS16;
|
||||
if(immediate & 0x8000)
|
||||
immediate |= ~(0xffffull);
|
||||
break;
|
||||
case ENCODING_ID:
|
||||
type = TYPE_MOFFS32;
|
||||
if(immediate & 0x80000000)
|
||||
immediate |= ~(0xffffffffull);
|
||||
break;
|
||||
case ENCODING_IO:
|
||||
type = TYPE_MOFFS64;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -292,25 +296,16 @@ static void translateImmediate(MCInst &mcInst, uint64_t immediate,
|
||||
case TYPE_REL8:
|
||||
isBranch = true;
|
||||
pcrel = insn.startLocation + insn.immediateOffset + insn.immediateSize;
|
||||
// fall through to sign extend the immediate if needed.
|
||||
case TYPE_MOFFS8:
|
||||
if(immediate & 0x80)
|
||||
immediate |= ~(0xffull);
|
||||
break;
|
||||
case TYPE_MOFFS16:
|
||||
if(immediate & 0x8000)
|
||||
immediate |= ~(0xffffull);
|
||||
break;
|
||||
case TYPE_REL32:
|
||||
case TYPE_REL64:
|
||||
isBranch = true;
|
||||
pcrel = insn.startLocation + insn.immediateOffset + insn.immediateSize;
|
||||
// fall through to sign extend the immediate if needed.
|
||||
case TYPE_MOFFS32:
|
||||
if(immediate & 0x80000000)
|
||||
immediate |= ~(0xffffffffull);
|
||||
break;
|
||||
case TYPE_MOFFS64:
|
||||
default:
|
||||
// operand is 64 bits wide. Do nothing.
|
||||
break;
|
||||
|
@ -215,3 +215,19 @@ void X86ATTInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
|
||||
|
||||
O << markup(">");
|
||||
}
|
||||
|
||||
void X86ATTInstPrinter::printMemOffset(const MCInst *MI, unsigned Op,
|
||||
raw_ostream &O) {
|
||||
const MCOperand &DispSpec = MI->getOperand(Op);
|
||||
|
||||
O << markup("<mem:");
|
||||
|
||||
if (DispSpec.isImm()) {
|
||||
O << formatImm(DispSpec.getImm());
|
||||
} else {
|
||||
assert(DispSpec.isExpr() && "non-immediate displacement?");
|
||||
O << *DispSpec.getExpr();
|
||||
}
|
||||
|
||||
O << markup(">");
|
||||
}
|
||||
|
@ -42,7 +42,8 @@ public:
|
||||
void printSSECC(const MCInst *MI, unsigned Op, raw_ostream &OS);
|
||||
void printAVXCC(const MCInst *MI, unsigned Op, raw_ostream &OS);
|
||||
void printPCRelImm(const MCInst *MI, unsigned OpNo, raw_ostream &OS);
|
||||
|
||||
void printMemOffset(const MCInst *MI, unsigned OpNo, raw_ostream &OS);
|
||||
|
||||
void printopaquemem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
|
||||
printMemReference(MI, OpNo, O);
|
||||
}
|
||||
@ -86,6 +87,19 @@ public:
|
||||
void printf512mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
|
||||
printMemReference(MI, OpNo, O);
|
||||
}
|
||||
|
||||
void printMemOffs8(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
|
||||
printMemOffset(MI, OpNo, O);
|
||||
}
|
||||
void printMemOffs16(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
|
||||
printMemOffset(MI, OpNo, O);
|
||||
}
|
||||
void printMemOffs32(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
|
||||
printMemOffset(MI, OpNo, O);
|
||||
}
|
||||
void printMemOffs64(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
|
||||
printMemOffset(MI, OpNo, O);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -200,3 +200,19 @@ void X86IntelInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
|
||||
|
||||
O << ']';
|
||||
}
|
||||
|
||||
void X86IntelInstPrinter::printMemOffset(const MCInst *MI, unsigned Op,
|
||||
raw_ostream &O) {
|
||||
const MCOperand &DispSpec = MI->getOperand(Op);
|
||||
|
||||
O << '[';
|
||||
|
||||
if (DispSpec.isImm()) {
|
||||
O << formatImm(DispSpec.getImm());
|
||||
} else {
|
||||
assert(DispSpec.isExpr() && "non-immediate displacement?");
|
||||
O << *DispSpec.getExpr();
|
||||
}
|
||||
|
||||
O << ']';
|
||||
}
|
||||
|
@ -39,7 +39,8 @@ public:
|
||||
void printSSECC(const MCInst *MI, unsigned Op, raw_ostream &O);
|
||||
void printAVXCC(const MCInst *MI, unsigned Op, raw_ostream &O);
|
||||
void printPCRelImm(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
|
||||
void printMemOffset(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
|
||||
void printopaquemem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
|
||||
O << "opaque ptr ";
|
||||
printMemReference(MI, OpNo, O);
|
||||
@ -97,6 +98,23 @@ public:
|
||||
O << "zmmword ptr ";
|
||||
printMemReference(MI, OpNo, O);
|
||||
}
|
||||
|
||||
void printMemOffs8(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
|
||||
O << "byte ptr ";
|
||||
printMemOffset(MI, OpNo, O);
|
||||
}
|
||||
void printMemOffs16(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
|
||||
O << "word ptr ";
|
||||
printMemOffset(MI, OpNo, O);
|
||||
}
|
||||
void printMemOffs32(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
|
||||
O << "dword ptr ";
|
||||
printMemOffset(MI, OpNo, O);
|
||||
}
|
||||
void printMemOffs64(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
|
||||
O << "qword ptr ";
|
||||
printMemOffset(MI, OpNo, O);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -439,17 +439,45 @@ let OperandType = "OPERAND_PCREL",
|
||||
def i32imm_pcrel : Operand<i32>;
|
||||
def i16imm_pcrel : Operand<i16>;
|
||||
|
||||
def offset8 : Operand<i64>;
|
||||
def offset16 : Operand<i64>;
|
||||
def offset32 : Operand<i64>;
|
||||
def offset64 : Operand<i64>;
|
||||
|
||||
// Branch targets have OtherVT type and print as pc-relative values.
|
||||
def brtarget : Operand<OtherVT>;
|
||||
def brtarget8 : Operand<OtherVT>;
|
||||
|
||||
}
|
||||
|
||||
def X86MemOffs8AsmOperand : AsmOperandClass {
|
||||
let Name = "MemOffs8";
|
||||
let SuperClasses = [X86Mem8AsmOperand];
|
||||
}
|
||||
def X86MemOffs16AsmOperand : AsmOperandClass {
|
||||
let Name = "MemOffs16";
|
||||
let SuperClasses = [X86Mem16AsmOperand];
|
||||
}
|
||||
def X86MemOffs32AsmOperand : AsmOperandClass {
|
||||
let Name = "MemOffs32";
|
||||
let SuperClasses = [X86Mem32AsmOperand];
|
||||
}
|
||||
def X86MemOffs64AsmOperand : AsmOperandClass {
|
||||
let Name = "MemOffs64";
|
||||
let SuperClasses = [X86Mem64AsmOperand];
|
||||
}
|
||||
|
||||
let OperandType = "OPERAND_MEMORY" in {
|
||||
def offset8 : Operand<i64> {
|
||||
let ParserMatchClass = X86MemOffs8AsmOperand;
|
||||
let PrintMethod = "printMemOffs8"; }
|
||||
def offset16 : Operand<i64> {
|
||||
let ParserMatchClass = X86MemOffs16AsmOperand;
|
||||
let PrintMethod = "printMemOffs16"; }
|
||||
def offset32 : Operand<i64> {
|
||||
let ParserMatchClass = X86MemOffs32AsmOperand;
|
||||
let PrintMethod = "printMemOffs32"; }
|
||||
def offset64 : Operand<i64> {
|
||||
let ParserMatchClass = X86MemOffs64AsmOperand;
|
||||
let PrintMethod = "printMemOffs64"; }
|
||||
}
|
||||
|
||||
|
||||
def SSECC : Operand<i8> {
|
||||
let PrintMethod = "printSSECC";
|
||||
let OperandType = "OPERAND_IMMEDIATE";
|
||||
@ -1104,13 +1132,13 @@ def MOV32ao32 : Ii32 <0xA3, RawFrm, (outs offset32:$dst), (ins),
|
||||
// These forms all have full 64-bit absolute addresses in their instructions
|
||||
// and use the movabs mnemonic to indicate this specific form.
|
||||
let mayLoad = 1 in {
|
||||
def MOV64o8a : RIi64_NOREX<0xA0, RawFrm, (outs), (ins offset64:$src),
|
||||
def MOV64o8a : RIi64_NOREX<0xA0, RawFrm, (outs), (ins offset8:$src),
|
||||
"movabs{b}\t{$src, %al|al, $src}", []>,
|
||||
Requires<[In64BitMode]>;
|
||||
def MOV64o16a : RIi64_NOREX<0xA1, RawFrm, (outs), (ins offset64:$src),
|
||||
def MOV64o16a : RIi64_NOREX<0xA1, RawFrm, (outs), (ins offset16:$src),
|
||||
"movabs{w}\t{$src, %ax|ax, $src}", []>, OpSize,
|
||||
Requires<[In64BitMode]>;
|
||||
def MOV64o32a : RIi64_NOREX<0xA1, RawFrm, (outs), (ins offset64:$src),
|
||||
def MOV64o32a : RIi64_NOREX<0xA1, RawFrm, (outs), (ins offset32:$src),
|
||||
"movabs{l}\t{$src, %eax|eax, $src}", []>,
|
||||
Requires<[In64BitMode]>;
|
||||
def MOV64o64a : RIi64<0xA1, RawFrm, (outs), (ins offset64:$src),
|
||||
@ -1119,13 +1147,13 @@ def MOV64o64a : RIi64<0xA1, RawFrm, (outs), (ins offset64:$src),
|
||||
}
|
||||
|
||||
let mayStore = 1 in {
|
||||
def MOV64ao8 : RIi64_NOREX<0xA2, RawFrm, (outs offset64:$dst), (ins),
|
||||
def MOV64ao8 : RIi64_NOREX<0xA2, RawFrm, (outs offset8:$dst), (ins),
|
||||
"movabs{b}\t{%al, $dst|$dst, al}", []>,
|
||||
Requires<[In64BitMode]>;
|
||||
def MOV64ao16 : RIi64_NOREX<0xA3, RawFrm, (outs offset64:$dst), (ins),
|
||||
def MOV64ao16 : RIi64_NOREX<0xA3, RawFrm, (outs offset16:$dst), (ins),
|
||||
"movabs{w}\t{%ax, $dst|$dst, ax}", []>, OpSize,
|
||||
Requires<[In64BitMode]>;
|
||||
def MOV64ao32 : RIi64_NOREX<0xA3, RawFrm, (outs offset64:$dst), (ins),
|
||||
def MOV64ao32 : RIi64_NOREX<0xA3, RawFrm, (outs offset32:$dst), (ins),
|
||||
"movabs{l}\t{%eax, $dst|$dst, eax}", []>,
|
||||
Requires<[In64BitMode]>;
|
||||
def MOV64ao64 : RIi64<0xA3, RawFrm, (outs offset64:$dst), (ins),
|
||||
|
@ -1,13 +1,31 @@
|
||||
# RUN: llvm-mc --disassemble %s -triple=i386 --output-asm-variant=1 | FileCheck %s
|
||||
|
||||
# CHECK: sgdt
|
||||
# CHECK: sgdt opaque ptr [eax]
|
||||
0x0f 0x01 0x00
|
||||
|
||||
# CHECK: sidt
|
||||
# CHECK: sidt opaque ptr [eax]
|
||||
0x0f 0x01 0x08
|
||||
|
||||
# CHECK: lgdt
|
||||
# CHECK: lgdt opaque ptr [eax]
|
||||
0x0f 0x01 0x10
|
||||
|
||||
# CHECK: lidt
|
||||
# CHECK: lidt opaque ptr [eax]
|
||||
0x0f 0x01 0x18
|
||||
|
||||
# CHECK: mov al, byte ptr [878082192]
|
||||
0xa0 0x90 0x78 0x56 0x34
|
||||
|
||||
# CHECK: mov ax, word ptr [878082192]
|
||||
0x66 0xa1 0x90 0x78 0x56 0x34
|
||||
|
||||
# CHECK: mov eax, dword ptr [878082192]
|
||||
0xa1 0x90 0x78 0x56 0x34
|
||||
|
||||
# CHECK: mov byte ptr [878082192], al
|
||||
0xa2 0x90 0x78 0x56 0x34
|
||||
|
||||
# CHECK: mov word ptr [878082192], ax
|
||||
0x66 0xa3 0x90 0x78 0x56 0x34
|
||||
|
||||
# CHECK: mov dword ptr [878082192], eax
|
||||
0xa3 0x90 0x78 0x56 0x34
|
||||
|
@ -119,3 +119,33 @@
|
||||
|
||||
# CHECK: xsaveopt64 opaque ptr [rax]
|
||||
0x48 0x0f 0xae 0x30
|
||||
|
||||
# CHECK: movabs al, byte ptr [-6066930261531658096]
|
||||
0xa0 0x90 0x78 0x56 0x34 0x12 0xef 0xcd 0xab
|
||||
|
||||
# CHECK: movabs al, byte ptr [-6066930261531658096]
|
||||
0x48 0xa0 0x90 0x78 0x56 0x34 0x12 0xef 0xcd 0xab
|
||||
|
||||
# CHECK: movabs ax, word ptr [-6066930261531658096]
|
||||
0x66 0xa1 0x90 0x78 0x56 0x34 0x12 0xef 0xcd 0xab
|
||||
|
||||
# CHECK: movabs eax, dword ptr [-6066930261531658096]
|
||||
0xa1 0x90 0x78 0x56 0x34 0x12 0xef 0xcd 0xab
|
||||
|
||||
# CHECK: movabs rax, qword ptr [-6066930261531658096]
|
||||
0x48 0xa1 0x90 0x78 0x56 0x34 0x12 0xef 0xcd 0xab
|
||||
|
||||
# CHECK: movabs byte ptr [-6066930261531658096], al
|
||||
0xa2 0x90 0x78 0x56 0x34 0x12 0xef 0xcd 0xab
|
||||
|
||||
# CHECK: movabs byte ptr [-6066930261531658096], al
|
||||
0x48 0xa2 0x90 0x78 0x56 0x34 0x12 0xef 0xcd 0xab
|
||||
|
||||
# CHECK: movabs word ptr [-6066930261531658096], ax
|
||||
0x66 0xa3 0x90 0x78 0x56 0x34 0x12 0xef 0xcd 0xab
|
||||
|
||||
# CHECK: movabs dword ptr [-6066930261531658096], eax
|
||||
0xa3 0x90 0x78 0x56 0x34 0x12 0xef 0xcd 0xab
|
||||
|
||||
# CHECK: movabs qword ptr [-6066930261531658096], rax
|
||||
0x48 0xa3 0x90 0x78 0x56 0x34 0x12 0xef 0xcd 0xab
|
||||
|
@ -648,3 +648,21 @@
|
||||
|
||||
# CHECK: adoxl (%eax), %eax
|
||||
0xf3 0x0f 0x38 0xf6 0x00
|
||||
|
||||
# CHECK: movb 878082192, %al
|
||||
0xa0 0x90 0x78 0x56 0x34
|
||||
|
||||
# CHECK: movw 878082192, %ax
|
||||
0x66 0xa1 0x90 0x78 0x56 0x34
|
||||
|
||||
# CHECK: movl 878082192, %eax
|
||||
0xa1 0x90 0x78 0x56 0x34
|
||||
|
||||
# CHECK: movb %al, 878082192
|
||||
0xa2 0x90 0x78 0x56 0x34
|
||||
|
||||
# CHECK: movw %ax, 878082192
|
||||
0x66 0xa3 0x90 0x78 0x56 0x34
|
||||
|
||||
# CHECK: movl %eax, 878082192
|
||||
0xa3 0x90 0x78 0x56 0x34
|
||||
|
Loading…
x
Reference in New Issue
Block a user