mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-06 06:33:24 +00:00
reject instructions that contain a \n in their asmstring. Mark
various X86 and ARM instructions that are bitten by this as isCodeGenOnly, as they are. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117884 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
25592eb52c
commit
4d1189f385
@ -311,6 +311,7 @@ let isCall = 1,
|
|||||||
T1Special<{1,1,1,?}>; // A6.2.3 & A8.6.24;
|
T1Special<{1,1,1,?}>; // A6.2.3 & A8.6.24;
|
||||||
|
|
||||||
// ARMv4T
|
// ARMv4T
|
||||||
|
let isCodeGenOnly = 1 in
|
||||||
def tBX : TIx2<{?,?,?,?,?}, {?,?}, ?,
|
def tBX : TIx2<{?,?,?,?,?}, {?,?}, ?,
|
||||||
(outs), (ins tGPR:$func, variable_ops), IIC_Br,
|
(outs), (ins tGPR:$func, variable_ops), IIC_Br,
|
||||||
"mov\tlr, pc\n\tbx\t$func",
|
"mov\tlr, pc\n\tbx\t$func",
|
||||||
@ -346,6 +347,7 @@ let isCall = 1,
|
|||||||
T1Special<{1,1,1,?}>; // A6.2.3 & A8.6.24
|
T1Special<{1,1,1,?}>; // A6.2.3 & A8.6.24
|
||||||
|
|
||||||
// ARMv4T
|
// ARMv4T
|
||||||
|
let isCodeGenOnly = 1 in
|
||||||
def tBXr9 : TIx2<{?,?,?,?,?}, {?,?}, ?,
|
def tBXr9 : TIx2<{?,?,?,?,?}, {?,?}, ?,
|
||||||
(outs), (ins tGPR:$func, variable_ops), IIC_Br,
|
(outs), (ins tGPR:$func, variable_ops), IIC_Br,
|
||||||
"mov\tlr, pc\n\tbx\t$func",
|
"mov\tlr, pc\n\tbx\t$func",
|
||||||
@ -365,6 +367,7 @@ let isBranch = 1, isTerminator = 1 in {
|
|||||||
def tBfar : TIx2<0b11110, 0b11, 1, (outs), (ins brtarget:$target), IIC_Br,
|
def tBfar : TIx2<0b11110, 0b11, 1, (outs), (ins brtarget:$target), IIC_Br,
|
||||||
"bl\t$target",[]>;
|
"bl\t$target",[]>;
|
||||||
|
|
||||||
|
let isCodeGenOnly = 1 in
|
||||||
def tBR_JTr : T1JTI<(outs),
|
def tBR_JTr : T1JTI<(outs),
|
||||||
(ins tGPR:$target, jtblock_operand:$jt, i32imm:$id),
|
(ins tGPR:$target, jtblock_operand:$jt, i32imm:$id),
|
||||||
IIC_Br, "mov\tpc, $target\n\t.align\t2$jt",
|
IIC_Br, "mov\tpc, $target\n\t.align\t2$jt",
|
||||||
|
@ -487,6 +487,7 @@ def ATOMSWAP6432 : I<0, Pseudo, (outs GR32:$dst1, GR32:$dst2),
|
|||||||
// Memory barriers
|
// Memory barriers
|
||||||
|
|
||||||
// TODO: Get this to fold the constant into the instruction.
|
// TODO: Get this to fold the constant into the instruction.
|
||||||
|
let isCodeGenOnly = 1 in
|
||||||
def OR32mrLocked : I<0x09, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$zero),
|
def OR32mrLocked : I<0x09, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$zero),
|
||||||
"lock\n\t"
|
"lock\n\t"
|
||||||
"or{l}\t{$zero, $dst|$dst, $zero}",
|
"or{l}\t{$zero, $dst|$dst, $zero}",
|
||||||
@ -498,7 +499,7 @@ def Int_MemBarrier : I<0, Pseudo, (outs), (ins),
|
|||||||
[(X86MemBarrier)]>, Requires<[HasSSE2]>;
|
[(X86MemBarrier)]>, Requires<[HasSSE2]>;
|
||||||
|
|
||||||
// TODO: Get this to fold the constant into the instruction.
|
// TODO: Get this to fold the constant into the instruction.
|
||||||
let hasSideEffects = 1, Defs = [ESP] in
|
let hasSideEffects = 1, Defs = [ESP], isCodeGenOnly = 1 in
|
||||||
def Int_MemBarrierNoSSE64 : RI<0x09, MRM1r, (outs), (ins GR64:$zero),
|
def Int_MemBarrierNoSSE64 : RI<0x09, MRM1r, (outs), (ins GR64:$zero),
|
||||||
"lock\n\t"
|
"lock\n\t"
|
||||||
"or{q}\t{$zero, (%rsp)|(%rsp), $zero}",
|
"or{q}\t{$zero, (%rsp)|(%rsp), $zero}",
|
||||||
@ -507,7 +508,7 @@ def Int_MemBarrierNoSSE64 : RI<0x09, MRM1r, (outs), (ins GR64:$zero),
|
|||||||
|
|
||||||
|
|
||||||
// Optimized codegen when the non-memory output is not used.
|
// Optimized codegen when the non-memory output is not used.
|
||||||
let Defs = [EFLAGS], mayLoad = 1, mayStore = 1 in {
|
let Defs = [EFLAGS], mayLoad = 1, mayStore = 1, isCodeGenOnly = 1 in {
|
||||||
def LOCK_ADD8mr : I<0x00, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src2),
|
def LOCK_ADD8mr : I<0x00, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src2),
|
||||||
"lock\n\t"
|
"lock\n\t"
|
||||||
"add{b}\t{$src2, $dst|$dst, $src2}", []>, LOCK;
|
"add{b}\t{$src2, $dst|$dst, $src2}", []>, LOCK;
|
||||||
@ -614,34 +615,35 @@ def LOCK_DEC64m : RI<0xFF, MRM1m, (outs), (ins i64mem:$dst),
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Atomic compare and swap.
|
// Atomic compare and swap.
|
||||||
let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in {
|
let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX],
|
||||||
|
isCodeGenOnly = 1 in {
|
||||||
def LCMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$ptr),
|
def LCMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$ptr),
|
||||||
"lock\n\t"
|
"lock\n\t"
|
||||||
"cmpxchg8b\t$ptr",
|
"cmpxchg8b\t$ptr",
|
||||||
[(X86cas8 addr:$ptr)]>, TB, LOCK;
|
[(X86cas8 addr:$ptr)]>, TB, LOCK;
|
||||||
}
|
}
|
||||||
let Defs = [AL, EFLAGS], Uses = [AL] in {
|
let Defs = [AL, EFLAGS], Uses = [AL], isCodeGenOnly = 1 in {
|
||||||
def LCMPXCHG8 : I<0xB0, MRMDestMem, (outs), (ins i8mem:$ptr, GR8:$swap),
|
def LCMPXCHG8 : I<0xB0, MRMDestMem, (outs), (ins i8mem:$ptr, GR8:$swap),
|
||||||
"lock\n\t"
|
"lock\n\t"
|
||||||
"cmpxchg{b}\t{$swap, $ptr|$ptr, $swap}",
|
"cmpxchg{b}\t{$swap, $ptr|$ptr, $swap}",
|
||||||
[(X86cas addr:$ptr, GR8:$swap, 1)]>, TB, LOCK;
|
[(X86cas addr:$ptr, GR8:$swap, 1)]>, TB, LOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
let Defs = [AX, EFLAGS], Uses = [AX] in {
|
let Defs = [AX, EFLAGS], Uses = [AX], isCodeGenOnly = 1 in {
|
||||||
def LCMPXCHG16 : I<0xB1, MRMDestMem, (outs), (ins i16mem:$ptr, GR16:$swap),
|
def LCMPXCHG16 : I<0xB1, MRMDestMem, (outs), (ins i16mem:$ptr, GR16:$swap),
|
||||||
"lock\n\t"
|
"lock\n\t"
|
||||||
"cmpxchg{w}\t{$swap, $ptr|$ptr, $swap}",
|
"cmpxchg{w}\t{$swap, $ptr|$ptr, $swap}",
|
||||||
[(X86cas addr:$ptr, GR16:$swap, 2)]>, TB, OpSize, LOCK;
|
[(X86cas addr:$ptr, GR16:$swap, 2)]>, TB, OpSize, LOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
let Defs = [EAX, EFLAGS], Uses = [EAX] in {
|
let Defs = [EAX, EFLAGS], Uses = [EAX], isCodeGenOnly = 1 in {
|
||||||
def LCMPXCHG32 : I<0xB1, MRMDestMem, (outs), (ins i32mem:$ptr, GR32:$swap),
|
def LCMPXCHG32 : I<0xB1, MRMDestMem, (outs), (ins i32mem:$ptr, GR32:$swap),
|
||||||
"lock\n\t"
|
"lock\n\t"
|
||||||
"cmpxchg{l}\t{$swap, $ptr|$ptr, $swap}",
|
"cmpxchg{l}\t{$swap, $ptr|$ptr, $swap}",
|
||||||
[(X86cas addr:$ptr, GR32:$swap, 4)]>, TB, LOCK;
|
[(X86cas addr:$ptr, GR32:$swap, 4)]>, TB, LOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
let Defs = [RAX, EFLAGS], Uses = [RAX] in {
|
let Defs = [RAX, EFLAGS], Uses = [RAX], isCodeGenOnly = 1 in {
|
||||||
def LCMPXCHG64 : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$ptr, GR64:$swap),
|
def LCMPXCHG64 : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$ptr, GR64:$swap),
|
||||||
"lock\n\t"
|
"lock\n\t"
|
||||||
"cmpxchgq\t$swap,$ptr",
|
"cmpxchgq\t$swap,$ptr",
|
||||||
@ -649,7 +651,7 @@ def LCMPXCHG64 : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$ptr, GR64:$swap),
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Atomic exchange and add
|
// Atomic exchange and add
|
||||||
let Constraints = "$val = $dst", Defs = [EFLAGS] in {
|
let Constraints = "$val = $dst", Defs = [EFLAGS], isCodeGenOnly = 1 in {
|
||||||
def LXADD8 : I<0xC0, MRMSrcMem, (outs GR8:$dst), (ins GR8:$val, i8mem:$ptr),
|
def LXADD8 : I<0xC0, MRMSrcMem, (outs GR8:$dst), (ins GR8:$val, i8mem:$ptr),
|
||||||
"lock\n\t"
|
"lock\n\t"
|
||||||
"xadd{b}\t{$val, $ptr|$ptr, $val}",
|
"xadd{b}\t{$val, $ptr|$ptr, $val}",
|
||||||
|
@ -229,19 +229,21 @@ static bool IsAssemblerInstruction(StringRef Name,
|
|||||||
if (StringRef(Name).startswith("Int_") || StringRef(Name).endswith("_Int"))
|
if (StringRef(Name).startswith("Int_") || StringRef(Name).endswith("_Int"))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Ignore instructions with no .s string.
|
// Reject instructions with no .s string.
|
||||||
//
|
|
||||||
// FIXME: What are these?
|
|
||||||
if (CGI.AsmString.empty()) {
|
if (CGI.AsmString.empty()) {
|
||||||
PrintError(CGI.TheDef->getLoc(),
|
PrintError(CGI.TheDef->getLoc(),
|
||||||
"instruction with empty asm string");
|
"instruction with empty asm string");
|
||||||
throw std::string("ERROR: Invalid instruction for asm matcher");
|
throw std::string("ERROR: Invalid instruction for asm matcher");
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Hack; ignore any instructions with a newline in them.
|
// Reject any instructions with a newline in them, they should be marked
|
||||||
if (std::find(CGI.AsmString.begin(),
|
// isCodeGenOnly if they are pseudo instructions.
|
||||||
CGI.AsmString.end(), '\n') != CGI.AsmString.end())
|
if (CGI.AsmString.find('\n') != std::string::npos) {
|
||||||
return false;
|
PrintError(CGI.TheDef->getLoc(),
|
||||||
|
"multiline instruction is not valid for the asmparser, "
|
||||||
|
"mark it isCodeGenOnly");
|
||||||
|
throw std::string("ERROR: Invalid instruction");
|
||||||
|
}
|
||||||
|
|
||||||
// Reject instructions with attributes, these aren't something we can handle,
|
// Reject instructions with attributes, these aren't something we can handle,
|
||||||
// the target should be refactored to use operands instead of modifiers.
|
// the target should be refactored to use operands instead of modifiers.
|
||||||
@ -258,6 +260,7 @@ static bool IsAssemblerInstruction(StringRef Name,
|
|||||||
throw std::string("ERROR: Invalid instruction");
|
throw std::string("ERROR: Invalid instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: Should reject these.
|
||||||
if (Tokens[i][0] == '$' && !OperandNames.insert(Tokens[i]).second) {
|
if (Tokens[i][0] == '$' && !OperandNames.insert(Tokens[i]).second) {
|
||||||
DEBUG({
|
DEBUG({
|
||||||
errs() << "warning: '" << Name << "': "
|
errs() << "warning: '" << Name << "': "
|
||||||
|
Loading…
x
Reference in New Issue
Block a user