Index: llvm/lib/Target/M68k/M68kInstrArithmetic.td =================================================================== --- llvm/lib/Target/M68k/M68kInstrArithmetic.td +++ llvm/lib/Target/M68k/M68kInstrArithmetic.td @@ -955,3 +955,110 @@ defm : BitwisePat<"AND", and>; defm : BitwisePat<"OR", or>; defm : BitwisePat<"XOR", xor>; + +//===----------------------------------------------------------------------===// +// Floating point arithmetic instruction +//===----------------------------------------------------------------------===// + +let Defs = [FPS] in +class MxFArithBase_FF patterns> + : MxInst { + let Uses = !if(!eq(rounding, ""), [FPC], []); + + let Predicates = !if(!eq(rounding, ""), [AtLeastM68881], [AtLeastM68040]); +} + +class MxFPOpModeSelector single, bits<7> double, + bits<7> extended> { + bits<7> Mode = !cond(!eq(rounding, "s"): single, + !eq(rounding, "d"): double, + !eq(rounding, ""): extended); +} + +//===----------------------------------------------------------------------===// +// Unary floating point instruction +//===----------------------------------------------------------------------===// + +class MxFUnary_FF opmode> + : MxFArithBase_FF<(outs Opnd.Op:$dst), (ins Opnd.Op:$src), + "f"#rounding#mnemonic#".x\t$src, $dst", rounding, [(null_frag)]> { + let Inst = (ascend + (descend 0b1111, + /*COPROCESSOR ID*/0b001, + 0b000, + /*MODE+REGISTER*/0b000000), + (descend 0b0, /* R/M */ 0b0, 0b0, + /*SOURCE SPECIFIER*/ + (operand "$src", 3), + /*DESTINATION*/ + (operand "$dst", 3), + /*OPMODE*/ + opmode) + ); +} + +multiclass MxFUnaryOp single, bits<7> double, + bits<7> extended> { + foreach rounding = ["", "s", "d"] in { + defvar opmode = MxFPOpModeSelector.Mode; + + def F # !toupper(rounding) # !substr(NAME, 1) # "80fp_fp" + : MxFUnary_FF; + + let isCodeGenOnly = 1 in + foreach size = [32, 64] in + def F # !toupper(rounding) # !substr(NAME, 1) # size # "fp_fp" + : MxFUnary_FF("MxOp"#size#"AddrMode_fpr"), + rounding, mnemonic, opmode>; + } +} + +defm FABS : MxFUnaryOp<"abs", 0b1011000, 0b1011100, 0b0011000>; +defm FNEG : MxFUnaryOp<"neg", 0b1011010, 0b1011110, 0b0011010>; + +//===----------------------------------------------------------------------===// +// Binary floating point instruction +//===----------------------------------------------------------------------===// + +let Constraints = "$src = $dst" in +class MxFBinary_FF opmode> + : MxFArithBase_FF<(outs Opnd.Op:$dst), (ins Opnd.Op:$src, Opnd.Op:$opd), + "f"#rounding#mnemonic#".x\t$opd, $dst", rounding, [(null_frag)]> { + let Inst = (ascend + (descend 0b1111, + /*COPROCESSOR ID*/0b001, + 0b000, + /*MODE+REGISTER*/0b000000), + (descend 0b0, /* R/M */ 0b0, 0b0, + /*SOURCE SPECIFIER*/ + (operand "$opd", 3), + /*DESTINATION*/ + (operand "$dst", 3), + /*OPMODE*/ + opmode) + ); +} + +multiclass MxFBinaryOp single, bits<7> double, + bits<7> extended> { + foreach rounding = ["", "s", "d"] in { + defvar opmode = MxFPOpModeSelector.Mode; + + def F # !toupper(rounding) # !substr(NAME, 1) # "80fp_fp" + : MxFBinary_FF; + + let isCodeGenOnly = 1 in + foreach size = [32, 64] in + def F # !toupper(rounding) # !substr(NAME, 1) # size # "fp_fp" + : MxFBinary_FF("MxOp"#size#"AddrMode_fpr"), + rounding, mnemonic, opmode>; + } +} + +defm FADD : MxFBinaryOp<"add", 0b1100010, 0b1100110, 0b0100010>; +defm FSUB : MxFBinaryOp<"sub", 0b1101000, 0b1101100, 0b0101000>; +defm FMUL : MxFBinaryOp<"mul", 0b1100011, 0b1100111, 0b0100011>; +defm FDIV : MxFBinaryOp<"div", 0b1100000, 0b1100100, 0b0100000>; Index: llvm/test/MC/M68k/Arith/Classes/MxFBinary_FF.s =================================================================== --- /dev/null +++ llvm/test/MC/M68k/Arith/Classes/MxFBinary_FF.s @@ -0,0 +1,49 @@ +; RUN: llvm-mc -triple=m68k -assemble -show-encoding -mcpu=M68040 %s | FileCheck %s + +; CHECK: fadd.x %fp0, %fp1 +; CHECK-SAME: ; encoding: [0xf2,0x00,0x00,0xa2] +fadd.x %fp0, %fp1 + +; CHECK: fsadd.x %fp2, %fp3 +; CHECK-SAME: ; encoding: [0xf2,0x00,0x09,0xe2] +fsadd.x %fp2, %fp3 + +; CHECK: fdadd.x %fp3, %fp4 +; CHECK-SAME: ; encoding: [0xf2,0x00,0x0e,0x66] +fdadd.x %fp3, %fp4 + +; CHECK: fsub.x %fp1, %fp2 +; CHECK-SAME: ; encoding: [0xf2,0x00,0x05,0x28] +fsub.x %fp1, %fp2 + +; CHECK: fssub.x %fp3, %fp4 +; CHECK-SAME; encoding: [0xf2,0x00,0x0e,0x68] +fssub.x %fp3, %fp4 + +; CHECK: fdsub.x %fp5, %fp6 +; CHECK-SAME; encoding: [0xf2,0x00,0x17,0x6c] +fdsub.x %fp5, %fp6 + +; CHECK: fmul.x %fp2, %fp3 +; CHECK-SAME; encoding: [0xf2,0x00,0x09,0xa3] +fmul.x %fp2, %fp3 + +; CHECK: fsmul.x %fp4, %fp5 +; CHECK-SAME; encoding: [0xf2,0x00,0x12,0xe3] +fsmul.x %fp4, %fp5 + +; CHECK: fdmul.x %fp6, %fp7 +; CHECK-SAME; encoding: [0xf2,0x00,0x1b,0xe7] +fdmul.x %fp6, %fp7 + +; CHECK: fdiv.x %fp3, %fp4 +; CHECK-SAME; encoding: [0xf2,0x00,0x0e,0x20] +fdiv.x %fp3, %fp4 + +; CHECK: fsdiv.x %fp5, %fp6 +; CHECK-SAME; encoding: [0xf2,0x00,0x17,0x60] +fsdiv.x %fp5, %fp6 + +; CHECK: fddiv.x %fp7, %fp0 +; CHECK-SAME; encoding: [0xf2,0x00,0x1c,0x64] +fddiv.x %fp7, %fp0 Index: llvm/test/MC/M68k/Arith/Classes/MxFUnary_FF.s =================================================================== --- /dev/null +++ llvm/test/MC/M68k/Arith/Classes/MxFUnary_FF.s @@ -0,0 +1,25 @@ +; RUN: llvm-mc -triple=m68k -assemble -show-encoding -mcpu=M68040 %s | FileCheck %s + +; CHECK: fabs.x %fp3, %fp2 +; CHECK-SAME: ; encoding: [0xf2,0x00,0x0d,0x18] +fabs.x %fp3, %fp2 + +; CHECK: fsabs.x %fp5, %fp7 +; CHECK-SAME: ; encoding: [0xf2,0x00,0x17,0xd8] +fsabs.x %fp5, %fp7 + +; CHECK: fdabs.x %fp0, %fp0 +; CHECK-SAME: ; encoding: [0xf2,0x00,0x00,0x5c] +fdabs.x %fp0, %fp0 + +; CHECK: fneg.x %fp0, %fp1 +; CHECK-SAME: ; encoding: [0xf2,0x00,0x00,0x9a] +fneg.x %fp0, %fp1 + +; CHECK: fsneg.x %fp2, %fp3 +; CHECK-SAME: ; encoding: [0xf2,0x00,0x09,0xda] +fsneg.x %fp2, %fp3 + +; CHECK: fdneg.x %fp4, %fp1 +; CHECK-SAME: ; encoding: [0xf2,0x00,0x10,0xde] +fdneg.x %fp4, %fp1