1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00
llvm-mirror/lib/Target/X86/X86InstrCMovSetCC.td
Craig Topper 1311b33688 [X86] Merge the different SETcc instructions for each condition code into single instructions that store the condition code as an operand.
Summary:
This avoids needing an isel pattern for each condition code. And it removes translation switches for converting between SETcc instructions and condition codes.

Now the printer, encoder and disassembler take care of converting the immediate. We use InstAliases to handle the assembly matching. But we print using the asm string in the instruction definition. The instruction itself is marked IsCodeGenOnly=1 to hide it from the assembly parser.

Reviewers: andreadb, courbet, RKSimon, spatel, lebedev.ri

Reviewed By: andreadb

Subscribers: hiraditya, lebedev.ri, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D60138

llvm-svn: 357801
2019-04-05 19:27:49 +00:00

111 lines
4.9 KiB
TableGen

//===-- X86InstrCMovSetCC.td - Conditional Move and SetCC --*- tablegen -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file describes the X86 conditional move and set on condition
// instructions.
//
//===----------------------------------------------------------------------===//
// CMOV instructions.
let isCodeGenOnly = 1, ForceDisassemble = 1 in {
let Uses = [EFLAGS], Predicates = [HasCMov], Constraints = "$src1 = $dst",
isCommutable = 1, SchedRW = [WriteCMOV] in {
def CMOV16rr
: I<0x40, MRMSrcRegCC, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2, ccode:$cond),
"cmov${cond}{w}\t{$src2, $dst|$dst, $src2}",
[(set GR16:$dst,
(X86cmov GR16:$src1, GR16:$src2, imm:$cond, EFLAGS))]>,
TB, OpSize16;
def CMOV32rr
: I<0x40, MRMSrcRegCC, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2, ccode:$cond),
"cmov${cond}{l}\t{$src2, $dst|$dst, $src2}",
[(set GR32:$dst,
(X86cmov GR32:$src1, GR32:$src2, imm:$cond, EFLAGS))]>,
TB, OpSize32;
def CMOV64rr
:RI<0x40, MRMSrcRegCC, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2, ccode:$cond),
"cmov${cond}{q}\t{$src2, $dst|$dst, $src2}",
[(set GR64:$dst,
(X86cmov GR64:$src1, GR64:$src2, imm:$cond, EFLAGS))]>, TB;
}
let Uses = [EFLAGS], Predicates = [HasCMov], Constraints = "$src1 = $dst",
SchedRW = [WriteCMOV.Folded, WriteCMOV.ReadAfterFold] in {
def CMOV16rm
: I<0x40, MRMSrcMemCC, (outs GR16:$dst), (ins GR16:$src1, i16mem:$src2, ccode:$cond),
"cmov${cond}{w}\t{$src2, $dst|$dst, $src2}",
[(set GR16:$dst, (X86cmov GR16:$src1, (loadi16 addr:$src2),
imm:$cond, EFLAGS))]>, TB, OpSize16;
def CMOV32rm
: I<0x40, MRMSrcMemCC, (outs GR32:$dst), (ins GR32:$src1, i32mem:$src2, ccode:$cond),
"cmov${cond}{l}\t{$src2, $dst|$dst, $src2}",
[(set GR32:$dst, (X86cmov GR32:$src1, (loadi32 addr:$src2),
imm:$cond, EFLAGS))]>, TB, OpSize32;
def CMOV64rm
:RI<0x40, MRMSrcMemCC, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2, ccode:$cond),
"cmov${cond}{q}\t{$src2, $dst|$dst, $src2}",
[(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
imm:$cond, EFLAGS))]>, TB;
} // Uses = [EFLAGS], Predicates = [HasCMov], Constraints = "$src1 = $dst"
} // isCodeGenOnly = 1, ForceDisassemble = 1
// SetCC instructions.
let Uses = [EFLAGS], isCodeGenOnly = 1, ForceDisassemble = 1 in {
def SETCCr : I<0x90, MRMXrCC, (outs GR8:$dst), (ins ccode:$cond),
"set${cond}\t$dst",
[(set GR8:$dst, (X86setcc imm:$cond, EFLAGS))]>,
TB, Sched<[WriteSETCC]>;
def SETCCm : I<0x90, MRMXmCC, (outs), (ins i8mem:$dst, ccode:$cond),
"set${cond}\t$dst",
[(store (X86setcc imm:$cond, EFLAGS), addr:$dst)]>,
TB, Sched<[WriteSETCCStore]>;
} // Uses = [EFLAGS]
multiclass CMOV_SETCC_Aliases<string Cond, int CC> {
def : InstAlias<"cmov"#Cond#"{w}\t{$src, $dst|$dst, $src}",
(CMOV16rr GR16:$dst, GR16:$src, CC), 0>;
def : InstAlias<"cmov"#Cond#"{w}\t{$src, $dst|$dst, $src}",
(CMOV16rm GR16:$dst, i16mem:$src, CC), 0>;
def : InstAlias<"cmov"#Cond#"{l}\t{$src, $dst|$dst, $src}",
(CMOV32rr GR32:$dst, GR32:$src, CC), 0>;
def : InstAlias<"cmov"#Cond#"{l}\t{$src, $dst|$dst, $src}",
(CMOV32rm GR32:$dst, i32mem:$src, CC), 0>;
def : InstAlias<"cmov"#Cond#"{q}\t{$src, $dst|$dst, $src}",
(CMOV64rr GR64:$dst, GR64:$src, CC), 0>;
def : InstAlias<"cmov"#Cond#"{q}\t{$src, $dst|$dst, $src}",
(CMOV64rm GR64:$dst, i64mem:$src, CC), 0>;
def : InstAlias<"set"#Cond#"\t$dst", (SETCCr GR8:$dst, CC), 0>;
def : InstAlias<"set"#Cond#"\t$dst", (SETCCm i8mem:$dst, CC), 0>;
}
defm : CMOV_SETCC_Aliases<"o" , 0>;
defm : CMOV_SETCC_Aliases<"no", 1>;
defm : CMOV_SETCC_Aliases<"b" , 2>;
defm : CMOV_SETCC_Aliases<"ae", 3>;
defm : CMOV_SETCC_Aliases<"e" , 4>;
defm : CMOV_SETCC_Aliases<"ne", 5>;
defm : CMOV_SETCC_Aliases<"be", 6>;
defm : CMOV_SETCC_Aliases<"a" , 7>;
defm : CMOV_SETCC_Aliases<"s" , 8>;
defm : CMOV_SETCC_Aliases<"ns", 9>;
defm : CMOV_SETCC_Aliases<"p" , 10>;
defm : CMOV_SETCC_Aliases<"np", 11>;
defm : CMOV_SETCC_Aliases<"l" , 12>;
defm : CMOV_SETCC_Aliases<"ge", 13>;
defm : CMOV_SETCC_Aliases<"le", 14>;
defm : CMOV_SETCC_Aliases<"g" , 15>;
// SALC is an undocumented instruction. Information for this instruction can be found
// here http://www.rcollins.org/secrets/opcodes/SALC.html
// Set AL if carry.
let Uses = [EFLAGS], Defs = [AL], SchedRW = [WriteALU] in {
def SALC : I<0xD6, RawFrm, (outs), (ins), "salc", []>, Requires<[Not64BitMode]>;
}