DataHoarder
e3535abed0
All checks were successful
continuous-integration/drone/push Build is passing
151 lines
7.6 KiB
NASM
151 lines
7.6 KiB
NASM
;; Standard Library
|
|
|
|
;; These registers are used within virtual functions as temporary holders
|
|
.constant std_SCRATCH_0 MGMT_SCRATCH_0
|
|
.constant std_SCRATCH_1 MGMT_SCRATCH_1
|
|
|
|
;; Also used as single return value
|
|
.reserve std_RETURN_VALUE 0x1E0
|
|
.reserve std_RETURN_VALUE_EXTRA 0x1E1
|
|
.reserve std_PARAMETER_0 0x1E2
|
|
.reserve std_PARAMETER_1 0x1E3
|
|
|
|
;; Used for offset pointer access
|
|
.constant std_THIS %0
|
|
|
|
.constant RRET std_RETURN_VALUE ;;Alias
|
|
.constant RRET_X std_RETURN_VALUE_EXTRA ;;Alias
|
|
.constant P0 std_PARAMETER_0
|
|
.constant P1 std_PARAMETER_1
|
|
.constant S0 std_SCRATCH_0
|
|
.constant S1 std_SCRATCH_1
|
|
|
|
;; These are offset registers to be called with <OP>~2 to access stack frame parameters
|
|
.constant P2 %0, +1 ;; Equivalent to same address in GET <Reg>, 1
|
|
.constant P3 %0, +2 ;; Equivalent to same address in GET <Reg>, 2
|
|
.constant P4 %0, +3 ;; Equivalent to same address in GET <Reg>, 3
|
|
.constant P5 %0, +4 ;; Equivalent to same address in GET <Reg>, 4
|
|
.constant P6 %0, +5 ;; Equivalent to same address in GET <Reg>, 5
|
|
.constant P7 %0, +6 ;; Equivalent to same address in GET <Reg>, 6
|
|
.constant P8 %0, +7 ;; Equivalent to same address in GET <Reg>, 7
|
|
.constant P9 %0, +8 ;; Equivalent to same address in GET <Reg>, 8
|
|
.constant P10 %0, +9 ;; Equivalent to same address in GET <Reg>, 9
|
|
.constant P11 %0, +10 ;; Equivalent to same address in GET <Reg>, 10
|
|
.constant P12 %0, +11 ;; Equivalent to same address in GET <Reg>, 11
|
|
.constant P13 %0, +12 ;; Equivalent to same address in GET <Reg>, 12
|
|
.constant P14 %0, +13 ;; Equivalent to same address in GET <Reg>, 13
|
|
.constant P15 %0, +14 ;; Equivalent to same address in GET <Reg>, 14
|
|
.constant P16 %0, +15 ;; Equivalent to same address in GET <Reg>, 15
|
|
|
|
;; These are parameter registers to be called with GET to access stack frame parameters
|
|
.constant GET_P2 1
|
|
.constant GET_P3 2
|
|
.constant GET_P4 3
|
|
.constant GET_P5 4
|
|
.constant GET_P6 5
|
|
.constant GET_P7 6
|
|
.constant GET_P8 7
|
|
.constant GET_P9 8
|
|
.constant GET_P10 9
|
|
.constant GET_P11 10
|
|
.constant GET_P12 11
|
|
.constant GET_P13 12
|
|
.constant GET_P14 13
|
|
.constant GET_P15 14
|
|
.constant GET_P16 15
|
|
|
|
;; Ephemeral registers to be used within functions. These values may not be kept when calling other functions. They can be used when returning values if necessary.
|
|
;; Some std functions might restore these values.
|
|
.reserve std_EPHEMERAL_REGISTER_0 0x1F0
|
|
.reserve std_EPHEMERAL_REGISTER_1 0x1F1
|
|
.reserve std_EPHEMERAL_REGISTER_2 0x1F2
|
|
.reserve std_EPHEMERAL_REGISTER_3 0x1F3
|
|
.reserve std_EPHEMERAL_REGISTER_4 0x1F4
|
|
.reserve std_EPHEMERAL_REGISTER_5 0x1F5
|
|
.reserve std_EPHEMERAL_REGISTER_6 0x1F6
|
|
.reserve std_EPHEMERAL_REGISTER_7 0x1F7
|
|
.reserve std_EPHEMERAL_REGISTER_8 0x1F8
|
|
.reserve std_EPHEMERAL_REGISTER_9 0x1F9
|
|
.reserve std_EPHEMERAL_REGISTER_10 0x1FA
|
|
.reserve std_EPHEMERAL_REGISTER_11 0x1FB
|
|
.reserve std_EPHEMERAL_REGISTER_12 0x1FC
|
|
.reserve std_EPHEMERAL_REGISTER_13 0x1FD
|
|
.reserve std_EPHEMERAL_REGISTER_14 0x1FE
|
|
.reserve std_EPHEMERAL_REGISTER_15 0x1FF
|
|
;; Abbreviations
|
|
.constant R0 std_EPHEMERAL_REGISTER_0
|
|
.constant R1 std_EPHEMERAL_REGISTER_1
|
|
.constant R2 std_EPHEMERAL_REGISTER_2
|
|
.constant R3 std_EPHEMERAL_REGISTER_3
|
|
.constant R4 std_EPHEMERAL_REGISTER_4
|
|
.constant R5 std_EPHEMERAL_REGISTER_5
|
|
.constant R6 std_EPHEMERAL_REGISTER_6
|
|
.constant R7 std_EPHEMERAL_REGISTER_7
|
|
.constant R8 std_EPHEMERAL_REGISTER_8
|
|
.constant R9 std_EPHEMERAL_REGISTER_9
|
|
.constant R10 std_EPHEMERAL_REGISTER_10
|
|
.constant R11 std_EPHEMERAL_REGISTER_11
|
|
.constant R12 std_EPHEMERAL_REGISTER_12
|
|
.constant R13 std_EPHEMERAL_REGISTER_13
|
|
.constant R14 std_EPHEMERAL_REGISTER_14
|
|
.constant R15 std_EPHEMERAL_REGISTER_15
|
|
|
|
|
|
; FASTCALL uint std_multiply(uint A, uint B). Return value on RRET
|
|
; Uses shift + add multiplication
|
|
.constant std_mul @std_multiply
|
|
.constant std_multiply @std_multiply
|
|
std_multiply:
|
|
MOV S0, P0 ; S0 = A
|
|
MOV S1, P1 ; S1 = B
|
|
MOV RRET, 0 ; result = 0
|
|
.multiply:
|
|
BEQ S0, 0, 0xFFFFFFFF, @.return ; continue if S0 != 0
|
|
BNE S0, 1, 0x1, @.skipBit ; If the lowest order bit is set in A?
|
|
ADD RRET, RRET, S1 ; result = result + b
|
|
.skipBit:
|
|
SHR S0, S0, 1 ; a = a >> 1, no sign copy
|
|
ADD S1, S1, S1 ; b = b + b
|
|
JUMP @.multiply
|
|
.return: RET ; Return, no need to get rid of stack as fastcall passed them on registers
|
|
|
|
|
|
; FASTCALL uint std_divide(uint dividend, uint divisor). Return quotient on RRET, remainder on RRET_X
|
|
; Uses shift + add division
|
|
; TODO: check validity
|
|
.constant std_div @std_divide
|
|
.constant std_divide @std_divide
|
|
std_divide:
|
|
BNE P1, 0, 0xffffffff, @.normal_division ; Handle divisor = 0
|
|
WRITE RRET, 0xffffffff, 0xffffffff ; Return both values 0xffffffff
|
|
JUMP @.return
|
|
|
|
.normal_division:
|
|
PUSH BSM_COUNTER_0 ; Save old value of counter
|
|
MOV BSM_COUNTER_0, 32 ; Move bits left to counter (8 * 4)
|
|
MOV RRET, P0 ; Move dividend to RRET (quotient)
|
|
MOV RRET_X, 0 ; Move remainder to RRET_X
|
|
MOV S0, 0
|
|
.divide:
|
|
MOV S0, RRET ; Move quotient to temp S0
|
|
ADD RRET, RRET, RRET ; quotient = quotient + quotient
|
|
ADD RRET_X, RRET_X, RRET_X ; remainder = remainder + remainder + ...
|
|
SHL S0, RRET, S0 ; quot << S0
|
|
ADD RRET_X, RRET_X, S0 ; remainder = ... + (quot << S0)
|
|
|
|
SUB S0, RRET_X, P1 ; compare rem >= divisor
|
|
BNE S0, 0, 1 <31, @.no_reduce
|
|
SUB RRET_X, RRET_X, P1 ; remainder = remainder - divisor
|
|
ADD RRET, RRET, 1 ; quotient = quotient + 1
|
|
.no_reduce:
|
|
LOOP @.divide ; Check if 0, if not, decrease bits left and go back. Use COUNTER[0]
|
|
|
|
POP BSM_COUNTER_0 ; Restore old value of counter
|
|
.return: RET ; Return, no need to get rid of stack as fastcall passed them on registers
|
|
|
|
|
|
|
|
;; x86-like definitions
|
|
.constant ebp, rrcc_FRAME_POINTER
|
|
.constant esp, rrcc_STACK_POINTER
|
|
.constant eax, RRET |