libc-full.M1 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. ## Copyright (C) 2016 Jeremiah Orians
  2. ## This file is part of M2-Planet.
  3. ##
  4. ## M2-Planet is free software: you can redistribute it and/or modify
  5. ## it under the terms of the GNU General Public License as published by
  6. ## the Free Software Foundation, either version 3 of the License, or
  7. ## (at your option) any later version.
  8. ##
  9. ## M2-Planet is distributed in the hope that it will be useful,
  10. ## but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ## GNU General Public License for more details.
  13. ##
  14. ## You should have received a copy of the GNU General Public License
  15. ## along with M2-Planet. If not, see <http://www.gnu.org/licenses/>.
  16. :_start
  17. '0' SP BP NO_SHIFT MOVE_ALWAYS ; Setup Base Pointer
  18. ;; Prepare argv
  19. !4 R0 ADD BP ARITH_ALWAYS ; ARGV_address = BP + 4
  20. {R0} PUSH_ALWAYS ; Put argv on the stack
  21. ;; Prepare envp
  22. '0' BP R0 NO_SHIFT MOVE_ALWAYS ; Address we need to load from
  23. !0 R0 LOAD32 R0 MEMORY ; Get ARGC
  24. !2 R0 ADD R0 ARITH_ALWAYS ; OFFSET = ARGC + 2
  25. '0' R0 R0 '1' MOVE_ALWAYS ; OFFSET = OFFSET * WORDSIZE
  26. '0' R0 R0 ADD BP ARITH2_ALWAYS ; ENVP_address = BP + OFFSET
  27. {R0} PUSH_ALWAYS ; Put envp on the stack
  28. ;; Stack offset
  29. !4 BP ADD BP ARITH_ALWAYS ; Fix BP
  30. ^~FUNCTION___init_malloc CALL_ALWAYS ; Setup for malloc
  31. ^~FUNCTION___init_io CALL_ALWAYS ; Setup for FILE*
  32. ^~FUNCTION_main CALL_ALWAYS ; Jump right into main
  33. {R1} POP_ALWAYS ; Fix stack
  34. {R1} POP_ALWAYS ; Fix stack
  35. {R1} POP_ALWAYS ; Fix stack
  36. {R0} PUSH_ALWAYS ; put return on the stack
  37. {R0} PUSH_ALWAYS ; So that _exit will have it
  38. {R0} PUSH_ALWAYS ; So that _exit will have it
  39. :FUNCTION_exit
  40. ^~FUNCTION___kill_io CALL_ALWAYS
  41. :FUNCTION__exit
  42. !4 R0 SUB R12 ARITH_ALWAYS
  43. !0 R0 LOAD32 R0 MEMORY
  44. !1 R7 LOADI8_ALWAYS
  45. SYSCALL_ALWAYS ; exit
  46. # Unsigned Divide
  47. :divide
  48. {R4} PUSH_ALWAYS ; Protect R4
  49. {R3} PUSH_ALWAYS ; Protect R3
  50. {R2} PUSH_ALWAYS ; Protect R2
  51. '0' R0 R3 NO_SHIFT MOVE_ALWAYS ; MOV R3,R0
  52. '0' R1 R2 NO_SHIFT MOVE_ALWAYS ; MOV R2,R1
  53. !0 R0 LOADI8_ALWAYS ; MOV R0,#0
  54. !0 CMPI8 R2 IMM_ALWAYS ; CMP R2,#0
  55. !1 R0 SUB R0 ARITH_LT ; SUBLT R0,R0,#1
  56. !0 CMPI8 R3 IMM_ALWAYS ; CMP R3,#0
  57. !0 R3 RSUB R3 ARITH_LT ; RSBLT R3,R3,#0
  58. '0' R0 R0 MVN_LT ; MVNLT R0,R0
  59. '0' R0 R4 NO_SHIFT MOVE_ALWAYS ; MOV R4,R0
  60. !32 R0 LOADI8_ALWAYS ; MOV R0,#32.
  61. !0 R1 LOADI8_ALWAYS ; MOV R1,#0
  62. :divide_loop
  63. '0' R2 R2 ADDS R2 ARITH2_ALWAYS ; ADDS R2,R2,R2
  64. '0' R1 R1 ADCS R1 ARITH2_ALWAYS ; ADCS R1,R1,R1
  65. '0' R3 CMP R1 AUX_ALWAYS ; CMP R1,R3
  66. '0' R3 R1 SUB R1 ARITH2_GE ; SUBGE R1,R1,R3
  67. !1 R2 ADD R2 ARITH_GE ; ADDGE R2,R2,#1
  68. !1 R0 SUB R0 ARITH_ALWAYS ; SUB R0,R0,#1
  69. !0 CMPI8 R0 IMM_ALWAYS ; CMP R0,#0
  70. ^~divide_loop JUMP_NE ; BNE loop
  71. '0' R2 R0 NO_SHIFT MOVE_ALWAYS ; MOV R0,R2
  72. {R2} POP_ALWAYS ; Restore R2
  73. {R3} POP_ALWAYS ; Restore R3
  74. {R4} POP_ALWAYS ; Restore R4
  75. '1' LR RETURN
  76. # Signed Divide
  77. :divides
  78. {R4} PUSH_ALWAYS ; Protect R4
  79. {R3} PUSH_ALWAYS ; Protect R3
  80. {R2} PUSH_ALWAYS ; Protect R2
  81. '0' R0 R3 NO_SHIFT MOVE_ALWAYS ; MOV R3,R0
  82. '0' R1 R2 NO_SHIFT MOVE_ALWAYS ; MOV R2,R1
  83. !0 R0 LOADI8_ALWAYS ; MOV R0,#0
  84. !0 CMPI8 R2 IMM_ALWAYS ; CMP R2,#0
  85. !0 R2 RSUB R2 ARITH_LT ; RSBLT R2,R2,#0
  86. !1 R0 SUB R0 ARITH_LT ; SUBLT R0,R0,#1
  87. !0 CMPI8 R3 IMM_ALWAYS ; CMP R3,#0
  88. !0 R3 RSUB R3 ARITH_LT ; RSBLT R3,R3,#0
  89. '0' R0 R0 MVN_LT ; MVNLT R0,R0
  90. '0' R0 R4 NO_SHIFT MOVE_ALWAYS ; MOV R4,R0
  91. !32 R0 LOADI8_ALWAYS ; MOV R0,#32.
  92. !0 R1 LOADI8_ALWAYS ; MOV R1,#0
  93. :divides_loop
  94. '0' R2 R2 ADDS R2 ARITH2_ALWAYS ; ADDS R2,R2,R2
  95. '0' R1 R1 ADCS R1 ARITH2_ALWAYS ; ADCS R1,R1,R1
  96. '0' R3 CMP R1 AUX_ALWAYS ; CMP R1,R3
  97. '0' R3 R1 SUB R1 ARITH2_GE ; SUBGE R1,R1,R3
  98. !1 R2 ADD R2 ARITH_GE ; ADDGE R2,R2,#1
  99. !1 R0 SUB R0 ARITH_ALWAYS ; SUB R0,R0,#1
  100. !0 CMPI8 R0 IMM_ALWAYS ; CMP R0,#0
  101. ^~divides_loop JUMP_NE ; BNE loop
  102. !0 CMPI8 R4 IMM_ALWAYS ; CMP R4,#0
  103. !0 R2 RSUB R2 ARITH_NE ; RSBNE R2,R2,#0
  104. '0' R2 R0 NO_SHIFT MOVE_ALWAYS ; MOV R0,R2
  105. {R2} POP_ALWAYS ; Restore R2
  106. {R3} POP_ALWAYS ; Restore R3
  107. {R4} POP_ALWAYS ; Restore R4
  108. '1' LR RETURN
  109. # Unsigned Modulus
  110. :modulus
  111. {LR} PUSH_ALWAYS ; Prepare to leverage divide
  112. ^~divide CALL_ALWAYS ; Use divide
  113. '0' R1 R0 NO_SHIFT MOVE_ALWAYS ; MOV R0,R1
  114. {LR} POP_ALWAYS ; Prepare for return
  115. '1' LR RETURN
  116. # Signed Modulus
  117. :moduluss
  118. {LR} PUSH_ALWAYS ; Prepare to leverage divide
  119. ^~divides CALL_ALWAYS ; Use divides
  120. '0' R1 R0 NO_SHIFT MOVE_ALWAYS ; MOV R0,R1
  121. {LR} POP_ALWAYS ; Prepare for return
  122. '1' LR RETURN
  123. :GLOBAL__envp
  124. NULL