Skip to content

Commit

Permalink
[m88k] Introduce instructions for div/divs and mul/mulu
Browse files Browse the repository at this point in the history
Uses guarded instructions because the mc88100 version may raise exceptions.
This implements issue #14.
  • Loading branch information
redstar committed Mar 1, 2024
1 parent a930309 commit efc916e
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 17 deletions.
18 changes: 13 additions & 5 deletions llvm/lib/Target/M88k/M88kInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -427,27 +427,35 @@ multiclass ArithTriCarry<bits<6> Func, string OpcStr, bit IsReMat = 0>
def rrcio : F_IRC<Func, /*carryin=*/0b1, /*carryout=*/0b1, OpcStr>;
}

// 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>;
Expand Down
24 changes: 12 additions & 12 deletions llvm/test/MC/M88k/valid.s
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
22 changes: 22 additions & 0 deletions llvm/test/MC/M88k/valid88110.s
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit efc916e

Please sign in to comment.