push_longlongint.s 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. .data
  2. .xdef push_longlongint
  3. .even
  4. push_longlongint:
  5. | Saving %d2 as well is a really dirty trick to reserve four extra bytes on the stack.
  6. | Only two are needed, but this is smaller than subtracting and adding.
  7. movem.l %d2-%d7/%a5,-(%sp)
  8. | Put address of push_quantum into %a5.
  9. move.l 0xC8,%a5
  10. move.l (%a5,3000),%a5 /* push_quantum */
  11. | %d7: Number of bytes.
  12. clr.w %d7
  13. | Put POSINT_TAG in %d6.
  14. moveq.l #31,%d6
  15. | Move parameter to %d3/%d4.
  16. movem.l 32(%sp),%d3-%d4
  17. | If negative, put NEGINT_TAG in %d6 and negate it.
  18. | We only need to look at %d3 because of how numbers are stored.
  19. tst.l %d3
  20. jbge .L__mainloop
  21. moveq.l #32,%d6
  22. neg.l %d4
  23. negx.l %d3
  24. .L__mainloop:
  25. | Finished if remaining value is zero.
  26. move.l %d3,%d0
  27. or.l %d4,%d0
  28. jbeq .L__finished
  29. | Push rightmost quantum of the value.
  30. move.w %d4,(%sp)
  31. jsr (%a5)
  32. | Add 1 to the number of bytes.
  33. addq.w #1,%d7
  34. | Shift the value to the right by one quantum.
  35. move.b %d3,%d4
  36. lsr.l #8,%d3
  37. ror.l #8,%d4
  38. | Always repeat the loop at this point.
  39. jbra .L__mainloop
  40. .L__finished:
  41. | Push number of bytes.
  42. move.w %d7,(%sp)
  43. jsr (%a5)
  44. | Push tag.
  45. move.w %d6,(%sp)
  46. jsr (%a5)
  47. | See above.
  48. | There is no problem in "restoring" %d2, since it may be trashed.
  49. movem.l (%sp)+,%d2-%d7/%a5
  50. rts