mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-14 00:32:55 +00:00
llvm-mc: A few more parsing / match tweaks.
- Operands which are just a label should be parsed as immediates, not memory operands (from the assembler perspective). - Match a few more flavors of immediates. - Distinguish match functions for memory operands which don't take a segment register. - We match the .s for "hello world" now! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@77745 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a0ee862f2e
commit
c09e411102
@ -135,6 +135,9 @@ struct X86Operand {
|
||||
}
|
||||
static X86Operand CreateMem(unsigned SegReg, MCValue Disp, unsigned BaseReg,
|
||||
unsigned IndexReg, unsigned Scale) {
|
||||
// We should never just have a displacement, that would be an immediate.
|
||||
assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
|
||||
|
||||
// The scale should always be one of {1,2,4,8}.
|
||||
assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
|
||||
"Invalid scale!");
|
||||
@ -216,7 +219,11 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) {
|
||||
// After parsing the base expression we could either have a parenthesized
|
||||
// memory address or not. If not, return now. If so, eat the (.
|
||||
if (getLexer().isNot(AsmToken::LParen)) {
|
||||
Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1);
|
||||
// Unless we have a segment register, treat this as an immediate.
|
||||
if (SegReg)
|
||||
Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1);
|
||||
else
|
||||
Op = X86Operand::CreateImm(Disp);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -238,7 +245,11 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) {
|
||||
// After parsing the base expression we could either have a parenthesized
|
||||
// memory address or not. If not, return now. If so, eat the (.
|
||||
if (getLexer().isNot(AsmToken::LParen)) {
|
||||
Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1);
|
||||
// Unless we have a segment register, treat this as an immediate.
|
||||
if (SegReg)
|
||||
Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1);
|
||||
else
|
||||
Op = X86Operand::CreateImm(Disp);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -377,10 +388,10 @@ Match_X86_Op_IMM(const X86Operand &Op, MCOperand *MCOps, unsigned NumOps) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool Match_X86_Op_MEM(const X86Operand &Op,
|
||||
static bool Match_X86_Op_LMEM(const X86Operand &Op,
|
||||
MCOperand *MCOps,
|
||||
unsigned NumMCOps) {
|
||||
assert(NumMCOps == 5 && "Invalid number of ops!");
|
||||
assert(NumMCOps == 4 && "Invalid number of ops!");
|
||||
|
||||
if (Op.Kind != X86Operand::Memory)
|
||||
return true;
|
||||
@ -389,6 +400,18 @@ static bool Match_X86_Op_MEM(const X86Operand &Op,
|
||||
MCOps[1].MakeImm(Op.getMemScale());
|
||||
MCOps[2].MakeReg(Op.getMemIndexReg());
|
||||
MCOps[3].MakeMCValue(Op.getMemDisp());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool Match_X86_Op_MEM(const X86Operand &Op,
|
||||
MCOperand *MCOps,
|
||||
unsigned NumMCOps) {
|
||||
assert(NumMCOps == 5 && "Invalid number of ops!");
|
||||
|
||||
if (Match_X86_Op_LMEM(Op, MCOps, 4))
|
||||
return true;
|
||||
|
||||
MCOps[4].MakeReg(Op.getMemSegReg());
|
||||
|
||||
return false;
|
||||
@ -413,15 +436,30 @@ REG(GR8)
|
||||
return Match_X86_Op_IMM(Op, MCOps, NumMCOps); \
|
||||
}
|
||||
|
||||
IMM(brtarget)
|
||||
IMM(brtarget8)
|
||||
IMM(i16i8imm)
|
||||
IMM(i16imm)
|
||||
IMM(i32i8imm)
|
||||
IMM(i32imm)
|
||||
IMM(i32imm_pcrel)
|
||||
IMM(i64i32imm)
|
||||
IMM(i64i32imm_pcrel)
|
||||
IMM(i64i8imm)
|
||||
IMM(i64imm)
|
||||
IMM(i8imm)
|
||||
|
||||
#define LMEM(name) \
|
||||
static bool Match_X86_Op_##name(const X86Operand &Op, \
|
||||
MCOperand *MCOps, \
|
||||
unsigned NumMCOps) { \
|
||||
return Match_X86_Op_LMEM(Op, MCOps, NumMCOps); \
|
||||
}
|
||||
|
||||
LMEM(lea32mem)
|
||||
LMEM(lea64_32mem)
|
||||
LMEM(lea64mem)
|
||||
|
||||
#define MEM(name) \
|
||||
static bool Match_X86_Op_##name(const X86Operand &Op, \
|
||||
MCOperand *MCOps, \
|
||||
@ -438,9 +476,6 @@ MEM(i16mem)
|
||||
MEM(i32mem)
|
||||
MEM(i64mem)
|
||||
MEM(i8mem)
|
||||
MEM(lea32mem)
|
||||
MEM(lea64_32mem)
|
||||
MEM(lea64mem)
|
||||
MEM(sdmem)
|
||||
MEM(ssmem)
|
||||
|
||||
@ -458,10 +493,6 @@ DUMMY(GR8_NOREX)
|
||||
DUMMY(RST)
|
||||
DUMMY(VR128)
|
||||
DUMMY(VR64)
|
||||
DUMMY(brtarget)
|
||||
DUMMY(brtarget8)
|
||||
DUMMY(i32imm_pcrel)
|
||||
DUMMY(i64i32imm_pcrel)
|
||||
DUMMY(i8mem_NOREX)
|
||||
|
||||
#include "X86GenAsmMatcher.inc"
|
||||
|
27
test/MC/AsmParser/hello.s
Normal file
27
test/MC/AsmParser/hello.s
Normal file
@ -0,0 +1,27 @@
|
||||
// RUN: llvm-mc %s -o -
|
||||
|
||||
.text
|
||||
.align 4,0x90
|
||||
.globl _main
|
||||
_main:
|
||||
pushl %ebp
|
||||
movl %esp, %ebp
|
||||
subl $8, %esp
|
||||
call "L1$pb"
|
||||
"L1$pb":
|
||||
popl %eax
|
||||
movl $0, -4(%ebp)
|
||||
movl %esp, %ecx
|
||||
leal L_.str-"L1$pb"(%eax), %eax
|
||||
movl %eax, (%ecx)
|
||||
call _printf
|
||||
movl $0, -4(%ebp)
|
||||
movl -4(%ebp), %eax
|
||||
addl $8, %esp
|
||||
popl %ebp
|
||||
ret
|
||||
.subsections_via_symbols
|
||||
.cstring
|
||||
L_.str:
|
||||
.asciz "hello world!\n"
|
||||
|
Loading…
x
Reference in New Issue
Block a user