push_longlongint.s 1.2 KB

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