On Sun, 14 Oct 2018, Philippe Mathieu-Daudé wrote: > > > + gen_move_low32(cpu_LO[acc], t2); > > > + gen_move_high32(cpu_HI[acc], t2); > > > + if (rd) { > > > + gen_move_low32(cpu_gpr[rd], t2); > > > > As above, are LO, HI and GPR[rd] sign-extended to 64 bits when required? > > MADDU rd, rs, rt > MADDU rs, rt > Multiply the contents of registers rs and rt as unsigned integers, > and add the doubleword (64-bit) > result to multiply/divide registers HI and LO. Also, store the lower > 32 bits of the add result in register > rd. In the MADDU rs, rt format, the store operation to a general > register is omitted. > > This one looks correct.
Obviously with processors such as the TX49 or the TX79 where GPRs are 64-bit for the purpose of integer arithmetic (i.e. any multimedia extension aside) any 32-bit results written to an integer register are implicitly sign-extended to the full 64-bit width of the destination register, as per the requirements of the MIPS architecture. Otherwise operation of any subsequent 32-bit instruction (other than SLL or SLLV) using that that result as an input operand would be unpredictable. You need to respect that in QEMU too. So results of individual operations are as in the comments with this code: mthi $0 # HI <- 0 mtlo $0 # LO <- 0 addiu $2, $0, 1 # $2 <- 1 lui $3, 0x4000 # $3 <- 0x40000000 maddu $4, $3, $2 # HI <- 0 # LO <- 0x40000000 # $4 <- 0x40000000 maddu $5, $4, $2 # HI <- 0 # LO <- 0xffffffff80000000 # $5 <- 0xffffffff80000000 maddu $6, $4, $2 # HI <- 1 # LO <- 0 # $6 <- 0 Similarly: addiu $2, $0, 1 # $2 <- 1 sll $3, $2, 31 # $3 <- 0xffffffff80000000 dsll $4, $2, 31 # $4 <- 0x80000000 dsll $5, $3, 0 # $5 <- 0xffffffff80000000 sll $6, $3, 0 # $6 <- 0xffffffff80000000 dsll $7, $4, 0 # $7 <- 0x80000000 sll $8, $4, 0 # $8 <- 0xffffffff80000000 daddu $9, $3, $3 # $9 <- 0xffffffff00000000 addu $10, $3, $3 # $10 <- 0 daddu $11, $4, $4 # $11 <- 0x100000000 addu $12, $4, $4 # unpredictable! HTH, Maciej