defm : BitwisePat<"AND", and>;
defm : BitwisePat<"OR", or>;
defm : BitwisePat<"XOR", xor>;
+
+//===----------------------------------------------------------------------===//
+// Floating point arithmetic instruction
+//===----------------------------------------------------------------------===//
+
+let Defs = [FPS] in
+class MxFArithBase_FF<dag outs, dag ins, string asm, string rounding,
+ list<dag> patterns>
+ : MxInst<outs, ins, asm, patterns> {
+ let Uses = !if(!eq(rounding, ""), [FPC], []);
+
+ let Predicates = !if(!eq(rounding, ""), [AtLeastM68881], [AtLeastM68040]);
+}
+
+class MxFPOpModeSelector<string rounding, bits<7> 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<MxOpBundle Opnd, string rounding,
+ string mnemonic, bits<7> 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<string mnemonic, bits<7> single, bits<7> double,
+ bits<7> extended> {
+ foreach rounding = ["", "s", "d"] in {
+ defvar opmode = MxFPOpModeSelector<rounding, single, double, extended>.Mode;
+
+ def F # !toupper(rounding) # !substr(NAME, 1) # "80fp_fp"
+ : MxFUnary_FF<MxOp80AddrMode_fpr, rounding, mnemonic, opmode>;
+
+ let isCodeGenOnly = 1 in
+ foreach size = [32, 64] in
+ def F # !toupper(rounding) # !substr(NAME, 1) # size # "fp_fp"
+ : MxFUnary_FF<!cast<MxOpBundle>("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<MxOpBundle Opnd, string rounding,
+ string mnemonic, bits<7> 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<string mnemonic, bits<7> single, bits<7> double,
+ bits<7> extended> {
+ foreach rounding = ["", "s", "d"] in {
+ defvar opmode = MxFPOpModeSelector<rounding, single, double, extended>.Mode;
+
+ def F # !toupper(rounding) # !substr(NAME, 1) # "80fp_fp"
+ : MxFBinary_FF<MxOp80AddrMode_fpr, rounding, mnemonic, opmode>;
+
+ let isCodeGenOnly = 1 in
+ foreach size = [32, 64] in
+ def F # !toupper(rounding) # !substr(NAME, 1) # size # "fp_fp"
+ : MxFBinary_FF<!cast<MxOpBundle>("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>;
--- /dev/null
+; 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
--- /dev/null
+; 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