-1

I am trying to write a single 68000 instruction to multiply the 32-bit unsigned value in D0 by 0.125. Yet fractional multiplication is not available. So I am wondering if there is any way to go around it? It's supposed to be unsigned and 0.125 = 1/8. Thus, the way I thought it would work is:

LSL (LSR #0,#3),D0

This didn't even run, and I have no idea how else I could do it.

Olsonist
  • 2,051
  • 1
  • 20
  • 35
  • 2
    Please read this as a precursor to assembly language: https://en.wikipedia.org/wiki/Three-address_code – Erik Eidt Oct 22 '20 at 02:36

2 Answers2

1

This is assembly, you cannot just compose expressions combining instructions like that. Each instruction needs to be on its own line. If you want to implement (x >> 3) << 3 you'll have to first shift right, then shift left, which are two separate instructions:

LSR.L #3,D0
LSL.L #3,D0

By the way, note that (x >> N) << N is equivalent to x & -(1 << N), which in the case of N=3 is: x & -8, or in 68k assembly AND.L #-8,D0 (or in hex AND.L #$fffffff7,D0).

However, if you want to just multiply by 0.125 (i.e. divide by 8), one right shift will suffice:

LSR.L #3,D0
Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128
  • If you want to round down to a multiple of 8, one `and` instruction can do it more efficiently than right + left shift. – Peter Cordes Oct 22 '20 at 02:17
  • @PeterCordes yep.. not sure what OP was after with that "instruction" really. – Marco Bonelli Oct 22 '20 at 02:18
  • Neither am I, but that's what your `lsr` + `lsl` combo does, so you should optimize it instead of suggesting that's a sequence of instructions you'd ever want to use in a program. I assume m68k has sign-extended immediates for AND instructions, or at worst that an `and` is no larger than 2 shifts. – Peter Cordes Oct 22 '20 at 02:19
  • @PeterCordes well, sure, but I wasn't trying to explain the optimal way of rounding, I was just explaining how to properly combine the instruction. What OP really wants is just a single shift. Whatever I'll just add it for the sake of it. – Marco Bonelli Oct 22 '20 at 02:22
  • `and #-8, d0` *does* implement `(x >> 3) << 3`. That's what compilers do (for other ISAs) https://godbolt.org/z/rf5qa8, so it's a bit of an overstatement to say you *have* to do it with shifts. That's only if you want to implement it *as written*. I see you already updated, but you got it backwards: `x & 7` is `x<<(16-3) >> (16-3)` to keep only the low 3 bits, instead of clearing those. – Peter Cordes Oct 22 '20 at 02:30
1

Not sure what you're trying to acheive with:

LSL (LSR #0,#3),D0

If you want to logical-shift-right the value in d0 by three bits (i.e., divide by 8, or multiply by 0.125), that would be the much simpler:

lsr #$03, d0 ;; or lsr.l
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953