From 5163a5b2a9077b10f331f5e415d899913d1cf09f Mon Sep 17 00:00:00 2001 From: Kai Nacke Date: Fri, 2 Feb 2024 18:54:53 -0500 Subject: [PATCH] [m88k] Introduce instructions for div/divs and mul/mulu Uses guarded instructions because the mc88100 version may raise exceptions. This implements issue #14. --- llvm/lib/Target/M88k/M88kInstrInfo.td | 18 +++++++++++++----- llvm/test/MC/M88k/valid.s | 24 ++++++++++++------------ llvm/test/MC/M88k/valid88110.s | 22 ++++++++++++++++++++++ 3 files changed, 47 insertions(+), 17 deletions(-) diff --git a/llvm/lib/Target/M88k/M88kInstrInfo.td b/llvm/lib/Target/M88k/M88kInstrInfo.td index edb7b6f2d751..d296580cf806 100644 --- a/llvm/lib/Target/M88k/M88kInstrInfo.td +++ b/llvm/lib/Target/M88k/M88kInstrInfo.td @@ -427,27 +427,35 @@ multiclass ArithTriCarry Func, string OpcStr, bit IsReMat = 0> def rrcio : F_IRC; } +// div and mul on the mc88100 are renamed to divs and mulu on the mc88110. +// The instructions are slightly different (the mc88100 version raises on +// exception when the FPU is disabled), therefore I defined guarded +// instructions. let isCommutable = 1 in { let isAdd = 1 in { defm ADDU : ArithTriCarry<0b011000, "addu", 1>; defm ADD : ArithTriCarry<0b011100, "add", 1>; } - defm MULU : ArithTri<0b011011, "mulu">; + let Predicates = [NotMC88110] in + defm MUL : ArithTri<0b011011, "mul">; } defm SUBU : ArithTriCarry<0b011001, "subu", 1>; defm SUB : ArithTriCarry<0b011101, "sub", 1>; defm DIVU : ArithTri<0b011010, "divu">; -defm DIVS : ArithTri<0b011110, "divs">; +let Predicates = [NotMC88110] in + defm DIV : ArithTri<0b011110, "div">; let isCompare = 1 in defm CMP : ArithTri<0b011111, "cmp">; -let Predicates = [MC88110] in { +let Predicates = [MC88110], DecoderNamespace = "MC88110" in { + defm DIVS : ArithTri<0b011110, "divs">; def DIVUrrd : F_IRCD<0b011010, GPR64Opnd, GPROpnd, "divu.d">; - let isCommutable = 1 in + let isCommutable = 1 in { + defm MULU : ArithTri<0b011011, "mulu">; def MULUrrd : F_IRCD<0b011011, GPROpnd, GPROpnd, "mulu.d">; + } } -// TODO Aliases div -> divs, mul -> mulu. Renames from 88100 defm : BinaryOpPat<"ADDU", add>; defm : BinaryOpPat<"SUBU", sub>; defm : BinaryOpPat<"MULU", mul>; diff --git a/llvm/test/MC/M88k/valid.s b/llvm/test/MC/M88k/valid.s index f1c543409966..036eec9a534b 100644 --- a/llvm/test/MC/M88k/valid.s +++ b/llvm/test/MC/M88k/valid.s @@ -278,12 +278,12 @@ isns: # CHECK: cmp %r0, %r2, 4096 | encoding: [0x7c,0x02,0x10,0x00] # signed integer divide - divs %r0, %r1, %r2 - divs %r0, %r1, 0 - divs %r0, %r1, 4096 -# CHECK: divs %r0, %r1, %r2 | encoding: [0xf4,0x01,0x78,0x02] -# CHECK: divs %r0, %r1, 0 | encoding: [0x78,0x01,0x00,0x00] -# CHECK: divs %r0, %r1, 4096 | encoding: [0x78,0x01,0x10,0x00] + div %r0, %r1, %r2 + div %r0, %r1, 0 + div %r0, %r1, 4096 +# CHECK: div %r0, %r1, %r2 | encoding: [0xf4,0x01,0x78,0x02] +# CHECK: div %r0, %r1, 0 | encoding: [0x78,0x01,0x00,0x00] +# CHECK: div %r0, %r1, 4096 | encoding: [0x78,0x01,0x10,0x00] # unsigned integer divide divu %r0, %r1, %r2 @@ -581,12 +581,12 @@ isns: # CHECK: mask.u %r0, %r1, 4096 | encoding: [0x4c,0x01,0x10,0x00] # integer multiply - mulu %r0, %r1, %r2 - mulu %r0, %r1, 0 - mulu %r0, %r1, 4096 -# CHECK: mulu %r0, %r1, %r2 | encoding: [0xf4,0x01,0x6c,0x02] -# CHECK: mulu %r0, %r1, 0 | encoding: [0x6c,0x01,0x00,0x00] -# CHECK: mulu %r0, %r1, 4096 | encoding: [0x6c,0x01,0x10,0x00] + mul %r0, %r1, %r2 + mul %r0, %r1, 0 + mul %r0, %r1, 4096 +# CHECK: mul %r0, %r1, %r2 | encoding: [0xf4,0x01,0x6c,0x02] +# CHECK: mul %r0, %r1, 0 | encoding: [0x6c,0x01,0x00,0x00] +# CHECK: mul %r0, %r1, 4096 | encoding: [0x6c,0x01,0x10,0x00] # floating point round to nearest integer nint.ss %r0, %r10 diff --git a/llvm/test/MC/M88k/valid88110.s b/llvm/test/MC/M88k/valid88110.s index 8d330de2827e..6e5161b70467 100644 --- a/llvm/test/MC/M88k/valid88110.s +++ b/llvm/test/MC/M88k/valid88110.s @@ -5,6 +5,18 @@ # instructions seems to be wrong. It's not possible to use gas/objdump to verify # the instructions in this file. +# signed integer divide + divs %r0, %r1, %r2 + divs %r0, %r1, 0 + divs %r0, %r1, 4096 +# CHECK: divs %r0, %r1, %r2 | encoding: [0xf4,0x01,0x78,0x02] +# CHECK: divs %r0, %r1, 0 | encoding: [0x78,0x01,0x00,0x00] +# CHECK: divs %r0, %r1, 4096 | encoding: [0x78,0x01,0x10,0x00] + +# unsigned integer divide + divu.d %r0, %r2, %r4 +# CHECK: divu.d %r0, %r2, %r4 | encoding: [0xf4,0x02,0x69,0x04] + isns: # floating point add fadd.sss %x0, %x1, %x2 @@ -390,6 +402,16 @@ isns: # load address lda.x %r2, %r3[%r4] +# integer multiply + mulu %r0, %r1, %r2 + mulu %r0, %r1, 0 + mulu %r0, %r1, 4096 + mulu.d %r2, %r4, %r5 +# CHECK: mulu %r0, %r1, %r2 | encoding: [0xf4,0x01,0x6c,0x02] +# CHECK: mulu %r0, %r1, 0 | encoding: [0x6c,0x01,0x00,0x00] +# CHECK: mulu %r0, %r1, 4096 | encoding: [0x6c,0x01,0x10,0x00] +# CHECK: mulu.d %r2, %r4, %r5 | encoding: [0xf4,0x44,0x6d,0x05] + # floating point round to nearest integer nint.ss %r1, %x10 nint.sd %r10, %x12