diff --git a/llvm/lib/Target/X86/X86InstrArithmetic.td b/llvm/lib/Target/X86/X86InstrArithmetic.td index 0582270285180..220ca31a825f9 100644 --- a/llvm/lib/Target/X86/X86InstrArithmetic.td +++ b/llvm/lib/Target/X86/X86InstrArithmetic.td @@ -277,31 +277,63 @@ class BinOpAIF_AF o, string m, X86TypeInfo t, Register areg, let SchedRW = [WriteADC]; } -// UnaryOpR - Instructions that read "reg" and write "reg". -class UnaryOpR o, Format f, string m, X86TypeInfo t, list p> - : ITy, Sched<[WriteALU]>; - -// UnaryOpM - Instructions that read "[mem]" and writes "[mem]". -class UnaryOpM o, Format f, string m, X86TypeInfo t, list p> - : ITy, - Sched<[WriteALURMW]> { +// UnaryOpR - Instructions that read "reg". +class UnaryOpR o, Format f, string m, string args, X86TypeInfo t, + dag out, list p> + : ITy, Sched<[WriteALU]>; +// UnaryOpR_R - Instructions that read "reg" and write "reg". +class UnaryOpR_R o, Format f, string m, X86TypeInfo t, + SDPatternOperator node> + : UnaryOpR; +// UnaryOpR_RF - Instructions that read "reg" and write "reg"/EFLAGS. +class UnaryOpR_RF o, Format f, string m, X86TypeInfo t, + SDPatternOperator node> + : UnaryOpR, DefEFLAGS; + +// UnaryOpM - Instructions that read "[mem]". +class UnaryOpM o, Format f, string m, string args, X86TypeInfo t, + dag out, list p> + : ITy { let mayLoad = 1; +} +// UnaryOpM_M - Instructions that read "[mem]" and writes "[mem]". +class UnaryOpM_M o, Format f, string m, X86TypeInfo t, + SDPatternOperator node> + : UnaryOpM, + Sched<[WriteALURMW]>{ + let mayStore = 1; +} +// UnaryOpM_MF - Instructions that read "[mem]" and writes "[mem]"/EFLAGS. +class UnaryOpM_MF o, Format f, string m, X86TypeInfo t, + SDPatternOperator node> + : UnaryOpM, Sched<[WriteALURMW]>, DefEFLAGS { let mayStore = 1; } //===----------------------------------------------------------------------===// // MUL/IMUL and DIV/IDIV Instructions // -class MulOpR o, Format f, string m, X86TypeInfo t, +class MulDivOpR o, Format f, string m, X86TypeInfo t, X86FoldableSchedWrite sched, list p> - : ITy, Sched<[sched]>; + : UnaryOpR { + let SchedRW = [sched]; +} -class MulOpM o, Format f, string m, X86TypeInfo t, +class MulDivOpM o, Format f, string m, X86TypeInfo t, X86FoldableSchedWrite sched, list p> - : ITy, SchedLoadReg { - let mayLoad = 1; + : UnaryOpM { + let SchedRW = + [sched.Folded, + // Memory operand. + ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault, + // Register reads (implicit or explicit). + sched.ReadAfterFold, sched.ReadAfterFold]; } multiclass Mul o, string m, Format RegMRM, Format MemMRM, SDPatternOperator node> { @@ -312,23 +344,23 @@ multiclass Mul o, string m, Format RegMRM, Format MemMRM, SDPatternOpera // This probably ought to be moved to a def : Pat<> if the // syntax can be accepted. let Defs = [AL,EFLAGS,AX], Uses = [AL] in - def 8r : MulOpR; let Defs = [AX,DX,EFLAGS], Uses = [AX] in - def 16r : MulOpR, OpSize16; + def 16r : MulDivOpR, OpSize16; let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in - def 32r : MulOpR, OpSize32; + def 32r : MulDivOpR, OpSize32; let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in - def 64r : MulOpR; + def 64r : MulDivOpR; let Defs = [AL,EFLAGS,AX], Uses = [AL] in - def 8m : MulOpM; let Defs = [AX,DX,EFLAGS], Uses = [AX] in - def 16m : MulOpM, OpSize16; + def 16m : MulDivOpM, OpSize16; let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in - def 32m : MulOpM, OpSize32; + def 32m : MulDivOpM, OpSize32; let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in - def 64m : MulOpM, Requires<[In64BitMode]>; + def 64m : MulDivOpM, Requires<[In64BitMode]>; } defm MUL : Mul<0xF7, "mul", MRM4r, MRM4m, mul>; @@ -340,21 +372,21 @@ multiclass Div o, string m, Format RegMRM, Format MemMRM> { defvar sched32 = !if(!eq(m, "div"), WriteDiv32, WriteIDiv32); defvar sched64 = !if(!eq(m, "div"), WriteDiv64, WriteIDiv64); let Defs = [AL,AH,EFLAGS], Uses = [AX] in - def 8r : MulOpR; + def 8r : MulDivOpR; let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in - def 16r : MulOpR, OpSize16; + def 16r : MulDivOpR, OpSize16; let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in - def 32r : MulOpR, OpSize32; + def 32r : MulDivOpR, OpSize32; let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in - def 64r : MulOpR; + def 64r : MulDivOpR; let Defs = [AL,AH,EFLAGS], Uses = [AX] in - def 8m : MulOpM; + def 8m : MulDivOpM; let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in - def 16m : MulOpM, OpSize16; + def 16m : MulDivOpM, OpSize16; let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in - def 32m : MulOpM, OpSize32; + def 32m : MulDivOpM, OpSize32; let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in - def 64m : MulOpM, Requires<[In64BitMode]>; + def 64m : MulDivOpM, Requires<[In64BitMode]>; } let hasSideEffects = 1 in { // so that we don't speculatively execute defm DIV: Div<0xF7, "div", MRM6r, MRM6m>; @@ -426,92 +458,84 @@ def IMUL64rmi32 : IMulOpMI_R; //===----------------------------------------------------------------------===// // INC and DEC Instructions // -class INCDECR - : UnaryOpR<0xFF, f, m, t, - [(set t.RegClass:$dst, EFLAGS, (node t.RegClass:$src1, 1))]>, - DefEFLAGS { - let isConvertibleToThreeAddress = 1; // Can xform into LEA. +class IncOpR_RF : UnaryOpR_RF<0xFF, MRM0r, "inc", t, null_frag> { + let Pattern = [(set t.RegClass:$dst, EFLAGS, + (X86add_flag_nocf t.RegClass:$src, 1))]; } -class INCDECM - : UnaryOpM<0xFF, f, m, t, - [(store (add (t.LoadNode addr:$dst), num), addr:$dst), - (implicit EFLAGS)]>, DefEFLAGS; -// INCDECR_ALT - Instructions like "inc reg" short forms. -class INCDECR_ALT o, string m, X86TypeInfo t> - : UnaryOpR, DefEFLAGS { - // Short forms only valid in 32-bit mode. Selected during MCInst lowering. - let Predicates = [Not64BitMode]; +class DecOpR_RF : UnaryOpR_RF<0xFF, MRM1r, "dec", t, null_frag> { + let Pattern = [(set t.RegClass:$dst, EFLAGS, + (X86sub_flag_nocf t.RegClass:$src, 1))]; } -let Constraints = "$src1 = $dst" in { -def INC16r_alt : INCDECR_ALT<0x40, "inc", Xi16>, OpSize16; -def INC32r_alt : INCDECR_ALT<0x40, "inc", Xi32>, OpSize32; -def INC8r : INCDECR; -def INC16r : INCDECR, OpSize16; -def INC32r : INCDECR, OpSize32; -def INC64r : INCDECR; -def DEC16r_alt : INCDECR_ALT<0x48, "dec", Xi16>, OpSize16; -def DEC32r_alt : INCDECR_ALT<0x48, "dec", Xi32>, OpSize32; -def DEC8r : INCDECR; -def DEC16r : INCDECR, OpSize16; -def DEC32r : INCDECR, OpSize32; -def DEC64r : INCDECR; +class IncOpM_M : UnaryOpM_MF<0xFF, MRM0m, "inc", t, null_frag> { + let Pattern = [(store (add (t.LoadNode addr:$src), 1), addr:$src), + (implicit EFLAGS)]; +} +class DecOpM_M : UnaryOpM_MF<0xFF, MRM1m, "dec", t, null_frag> { + let Pattern = [(store (add (t.LoadNode addr:$src), -1), addr:$src), + (implicit EFLAGS)]; +} +// IncDec_Alt - Instructions like "inc reg" short forms. +// Short forms only valid in 32-bit mode. Selected during MCInst lowering. +class IncDec_Alt o, string m, X86TypeInfo t> + : UnaryOpR_RF, Requires<[Not64BitMode]>; + +let Constraints = "$src = $dst", isConvertibleToThreeAddress = 1 in { +def INC16r_alt : IncDec_Alt<0x40, "inc", Xi16>, OpSize16; +def INC32r_alt : IncDec_Alt<0x40, "inc", Xi32>, OpSize32; +def DEC16r_alt : IncDec_Alt<0x48, "dec", Xi16>, OpSize16; +def DEC32r_alt : IncDec_Alt<0x48, "dec", Xi32>, OpSize32; +def INC8r : IncOpR_RF; +def INC16r : IncOpR_RF, OpSize16; +def INC32r : IncOpR_RF, OpSize32; +def INC64r : IncOpR_RF; +def DEC8r : DecOpR_RF; +def DEC16r : DecOpR_RF, OpSize16; +def DEC32r : DecOpR_RF, OpSize32; +def DEC64r : DecOpR_RF; } let Predicates = [UseIncDec] in { -def INC8m : INCDECM; -def INC16m : INCDECM, OpSize16; -def INC32m : INCDECM, OpSize32; -def DEC8m : INCDECM; -def DEC16m : INCDECM, OpSize16; -def DEC32m : INCDECM, OpSize32; +def INC8m : IncOpM_M; +def INC16m : IncOpM_M, OpSize16; +def INC32m : IncOpM_M, OpSize32; +def DEC8m : DecOpM_M; +def DEC16m : DecOpM_M, OpSize16; +def DEC32m : DecOpM_M, OpSize32; } let Predicates = [UseIncDec, In64BitMode] in { -def INC64m : INCDECM; -def DEC64m : INCDECM; +def INC64m : IncOpM_M; +def DEC64m : DecOpM_M; } //===----------------------------------------------------------------------===// // NEG and NOT Instructions // -class NegOpR o, string m, X86TypeInfo t> - : UnaryOpR, DefEFLAGS; -class NegOpM o, string m, X86TypeInfo t> - : UnaryOpM, DefEFLAGS; - -// NOTE: NOT does not set EFLAGS! -class NotOpR o, string m, X86TypeInfo t> - : UnaryOpR; - -class NotOpM o, string m, X86TypeInfo t> - : UnaryOpM; - -let Constraints = "$src1 = $dst" in { -def NEG8r : NegOpR<0xF6, "neg", Xi8>; -def NEG16r : NegOpR<0xF7, "neg", Xi16>, OpSize16; -def NEG32r : NegOpR<0xF7, "neg", Xi32>, OpSize32; -def NEG64r : NegOpR<0xF7, "neg", Xi64>; +class NegOpR_RF : UnaryOpR_RF<0xF7, MRM3r, "neg", t, ineg>; +class NegOpM_MF : UnaryOpM_MF<0xF7, MRM3m, "neg", t, ineg>; + +class NotOpR_R : UnaryOpR_R<0xF7, MRM2r, "not", t, not>; +class NotOpM_M : UnaryOpM_M<0xF7, MRM2m, "not", t, not>; + +let Constraints = "$src = $dst" in { +def NEG8r : NegOpR_RF; +def NEG16r : NegOpR_RF, OpSize16; +def NEG32r : NegOpR_RF, OpSize32; +def NEG64r : NegOpR_RF; + +def NOT8r : NotOpR_R; +def NOT16r : NotOpR_R, OpSize16; +def NOT32r : NotOpR_R, OpSize32; +def NOT64r : NotOpR_R; } -def NEG8m : NegOpM<0xF6, "neg", Xi8>; -def NEG16m : NegOpM<0xF7, "neg", Xi16>, OpSize16; -def NEG32m : NegOpM<0xF7, "neg", Xi32>, OpSize32; -def NEG64m : NegOpM<0xF7, "neg", Xi64>, Requires<[In64BitMode]>; - -let Constraints = "$src1 = $dst" in { -def NOT8r : NotOpR<0xF6, "not", Xi8>; -def NOT16r : NotOpR<0xF7, "not", Xi16>, OpSize16; -def NOT32r : NotOpR<0xF7, "not", Xi32>, OpSize32; -def NOT64r : NotOpR<0xF7, "not", Xi64>; -} +def NEG8m : NegOpM_MF; +def NEG16m : NegOpM_MF, OpSize16; +def NEG32m : NegOpM_MF, OpSize32; +def NEG64m : NegOpM_MF, Requires<[In64BitMode]>; -def NOT8m : NotOpM<0xF6, "not", Xi8>; -def NOT16m : NotOpM<0xF7, "not", Xi16>, OpSize16; -def NOT32m : NotOpM<0xF7, "not", Xi32>, OpSize32; -def NOT64m : NotOpM<0xF7, "not", Xi64>, Requires<[In64BitMode]>; +def NOT8m : NotOpM_M; +def NOT16m : NotOpM_M, OpSize16; +def NOT32m : NotOpM_M, OpSize32; +def NOT64m : NotOpM_M, Requires<[In64BitMode]>; /// ArithBinOp_RF - This is an arithmetic binary operator where the pattern is /// defined with "(set GPR:$dst, EFLAGS, (...". diff --git a/llvm/lib/Target/X86/X86InstrUtils.td b/llvm/lib/Target/X86/X86InstrUtils.td index 89f5653c04f2d..b7d2d8096ff54 100644 --- a/llvm/lib/Target/X86/X86InstrUtils.td +++ b/llvm/lib/Target/X86/X86InstrUtils.td @@ -99,17 +99,6 @@ class DisassembleOnly { bit ForceDisassemble = 1; } - -// SchedModel info for instruction that loads one value and gets the second -// (and possibly third) value from a register. -// This is used for instructions that put the memory operands before other -// uses. -class SchedLoadReg : Sched<[Sched.Folded, - // Memory operand. - ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault, - // Register reads (implicit or explicit). - Sched.ReadAfterFold, Sched.ReadAfterFold]>; - //===----------------------------------------------------------------------===// // X86 Type infomation definitions //===----------------------------------------------------------------------===// @@ -957,16 +946,15 @@ class MMXIi8 o, Format F, dag outs, dag ins, string asm, /// 2. Infers whether the instruction should have a 0x40 REX_W prefix. /// 3. Infers whether the low bit of the opcode should be 0 (for i8 operations) /// or 1 (for i16,i32,i64 operations). -class ITy opcode, Format f, X86TypeInfo typeinfo, dag outs, dag ins, - string mnemonic, string args, list pattern> - : I<{opcode{7}, opcode{6}, opcode{5}, opcode{4}, - opcode{3}, opcode{2}, opcode{1}, - !if(!eq(typeinfo.HasEvenOpcode, 1), 0, opcode{0})}, f, outs, ins, - !strconcat(mnemonic, "{", typeinfo.InstrSuffix, "}\t", args), pattern> { - +class ITy o, Format f, X86TypeInfo t, dag outs, dag ins, string m, + string args, list p> + : I<{o{7}, o{6}, o{5}, o{4}, o{3}, o{2}, o{1}, + !if(!eq(t.HasEvenOpcode, 1), 0, o{0})}, f, outs, ins, + !strconcat(m, "{", t.InstrSuffix, "}\t", args), p> { let hasSideEffects = 0; - let hasREX_W = typeinfo.HasREX_W; + let hasREX_W = t.HasREX_W; } +defvar unaryop_args = "$src"; defvar binop_args = "{$src2, $src1|$src1, $src2}"; defvar binop_ndd_args = "{$src2, $src1, $dst|$dst, $src1, $src2}";