#set jit_max_fixups = 128
#set jit_fixup_persistent_flag = %01
#set jit_fixup_live_flag       = %10

STRUCT jit_fixup_table
{
  .address	DCD 0
  .original	DCD 0
  .replace	DCD 0
  .size
}

STRUCT jit_module_fixup_table
{
  .title	DBB 32
  .offset	DCD 0
  .original	DCD 0
  .replace	DCD 0
  .size
}


;Entry:
; R0 = Command tail ([P] <addr/offset> <current> <new> [Module title])
; R1 = no. of parameters
; R12 = pointer to module private word

.Entry_JITMEMORYA
 STMFD   R13!, {R1-R3, R7-R11, R14}
 LDR     R12, [R12, #0]

 MOV     R7, R1				;R7=parameter count
 MOV     R9, #8				;R9=flags + pre-fetch

 LDRB    R2, [R12, #JIT_ARM4 - VARS]
 TEQ     R2, #0				;is the ARMv4 JIT active?
 ORRNE   R9, R9, #jit_fixup_persistent_flag	;YES, make persistent

 CMP     R7, #4				;4 parameters present?
 BLO     _P1				;NO
 LDRB    R1, [R0, #0]			;load char
 TEQ     R1, #ASC("p")			;is it "p"?
 TEQNE   R1, #ASC("P")			;NO, is it "P"?
 ORREQ   R9, R9, #jit_fixup_persistent_flag	;YES
 SUBEQ   R7, R7, #1			;reduce parameter count
 ADDEQ   R0, R0, #2			;skip parameter

 ._P1
 MOV     R1, R0				;command tail
 MOV     R0, #16			;base 16 number with restricted range
 SWI     XOS_ReadUnsigned		;read the value PRM1-460
 ADDVC   R9, R2, R9			;add flags and pre-fetch

 SWIVC   XOS_ReadUnsigned		;read the value PRM1-460
 MOVVC   R10, R2			;value it should be

 SWIVC   XOS_ReadUnsigned		;read the value PRM1-460
 MOVVC   R11, R2			;value to replace with
 LDMVSFD R13!, {R1-R3, R7-R11, PC}	;exit on error

 SUBS    R7, R7, #3			;reduce parameter count
 BEQ     _absolute			;no Module parameter

 BL      skip_spaces_R1
 SUB     R7, R1, #1			;R7=pointer to Module name

 LDR     R8, [R12, #JIT_module_fixups - VARS]
 TEQ     R8, #0				;have we allocated a fixup table?
 BNE     _P4				;YES

 MOV     R0, #Module_Claim		;NO, claim some memory
 MOV     R3, #4 + (jit_max_fixups * jit_module_fixup_table.size)
 SWI     XOS_Module			;PRM1-237
 LDMVSFD R13!, {R1-R3, R7-R11, PC}	;exit on error

 MOV     R8, R2				;our fixup table
 STR     R2, [R12, #JIT_module_fixups - VARS]
 MOV     R0, R2
 ADD     R1, R0, R3
 BL      ZeroBlock

 ._P4
 ADD     R0, R8, #4			;find spare fixup slot
 MOV     R1, #jit_max_fixups
 ._L3
   LDR     R2, [R0, #jit_module_fixup_table.offset]
   TEQ     R2, #0			;is slot spare?
   BEQ     _found_slot			;YES

   ADD     R0, R0, #jit_module_fixup_table.size
   SUBS    R1, R1, #1			;last slot?
 BNE     _L3				;NO

 MOV     R0, #1 << 31
 ADDS    R0, R0, R0			;set V
 ADR     R0, Error_No_JIT_Fixup_Space
 LDMFD   R13!, {R1-R3, R7-R11, PC}	;report error

 ._found_slot
 STR     R9, [R0, #jit_module_fixup_table.offset]	;store offset address
 STR     R10, [R0, #jit_module_fixup_table.original]	;store value it should be
 STR     R11, [R0, #jit_module_fixup_table.replace]	;store value to replace with

 ._L4spaces
   LDRB    R1, [R7], #1
   TEQ     R1, #32
   TEQNE   R1, #34				;quote
 BEQ     _L4spaces
 SUB     R7, R7, #1

 MOV     R2, #jit_module_fixup_table.offset	;max length
 ._L4						;copy module name
   LDRB    R1, [R7], #1
   TEQ     R1, #0
   TEQNE   R1, #13
   TEQNE   R1, #34
   MOVEQ   R1, #0			;terminate string
   STRB    R1, [R0], #1
   SUBNES  R2, R2, #1
 BNE     _L4

 LDR     R1, [R8, #0]
 ADD     R1, R1, #1			;increase fixup count
 STR     R1, [R8, #0]

LDMFD   R13!, {R1-R3, R7-R11, PC}


._absolute
 BL      add_JITMEMORYA			;add to replace table
LDMFD   R13!, {R1-R3, R7-R11, PC}




;add_JITMEMORYA
;--------------
;adds an entry to the JITMEMORYA table
;
;Entry:
; R9  - source address
; R10 - value it should be
; R11 - value to replace with
;
;Exit:
; R0  - error if VS or corrupt

.add_JITMEMORYA
 STMFD   R13!, {R1-R3, R8, R12, R14}
 ADR     R12, VARS

 LDR     R8, [R12, #JIT_fixups - VARS]
 TEQ     R8, #0				;have we allocated a fixup table?
 BNE     _P1				;YES

 MOV     R0, #Module_Claim		;NO, claim some memory
 MOV     R3, #4 + (jit_max_fixups * jit_fixup_table.size)
 SWI     XOS_Module			;PRM1-237
 LDMVSFD R13!, {R1-R3, R8, R12, PC}	;exit on error

 MOV     R8, R2				;our fixup table
 STR     R2, [R12, #JIT_fixups - VARS]
 MOV     R0, R2
 ADD     R1, R0, R3
 BL      ZeroBlock

 ._P1
 ADD     R0, R8, #4			;find spare fixup slot
 MOV     R1, #jit_max_fixups
 ._L2
   LDR     R2, [R0, #jit_fixup_table.address]
   TST     R2, #jit_fixup_live_flag	;is slot spare?
   BEQ     _found_slot			;YES

   ADD     R0, R0, #jit_fixup_table.size
   SUBS    R1, R1, #1			;last slot?
 BNE     _L2				;NO

 MOV     R0, #1 << 31
 ADDS    R0, R0, R0			;set V
 ADR     R0, Error_No_JIT_Fixup_Space
LDMFD   R13!, {R1-R3, R8, R12, PC}

 ._found_slot
 ORR     R9, R9, #jit_fixup_live_flag
 STR     R9, [R0, #jit_fixup_table.address]	;store address
 STR     R10, [R0, #jit_fixup_table.original]	;store value it should be
 STR     R11, [R0, #jit_fixup_table.replace]	;store value to replace with
      
 LDR     R1, [R8, #0]
 ADD     R1, R1, #1			;increase fixup count
 STR     R1, [R8, #0]
LDMFD   R13!, {R1-R3, R8, R12, PC}




;clear_jitmemorya
;----------------
;releases memory claimed for the jitmemorya table

;Entry:
; R12 - pointer to VARS

.clear_jitmemorya
 STMFD   R13!, {R0, R14}
 ADD     R0, R12, #JIT_fixups - VARS
 BL      release_RMA
 ADD     R0, R12, #JIT_module_fixups - VARS
 BL      release_RMA
LDMFD   R13!, {R0, PC}




;make_jitmemorya_persistent
;--------------------------
;changes any pending jitmemorya to be persistent
;required by the ARMv4 JIT to as OS_SynchroniseCodeAreas might wipe JIT'd code
;and lose any code changes

;Entry:
; R12 - pointer to VARS

.make_jitmemorya_persistent
 STMFD   R13!, {R0-R2, R14}

 LDR     R0, [R12, #JIT_fixups - VARS]
 TEQ     R0, #0				;have we allocated a fixup table?
 BEQ     _no_fixups			;NO

 ADD     R0, R0, #4			;R0=1st slot
 MOV     R1, #jit_max_fixups
 ._L1
   LDR     R2, [R0, #jit_fixup_table.address]
   TST     R2, #jit_fixup_live_flag	;is slot active?
   ORRNE   R2, R2, #jit_fixup_persistent_flag	;YES, make persistent
   STRNE   R2, [R0, #jit_fixup_table.address]

   ADD     R0, R0, #jit_fixup_table.size
   SUBS    R1, R1, #1			;last slot?
 BNE     _L1				;NO

 ._no_fixups
 LDR     R0, [R12, #JIT_module_fixups - VARS]
 TEQ     R0, #0				;have we allocated a fixup table?
 LDMEQFD R13!, {R0-R2, PC}

 ADD     R0, R0, #4			;R0=1st slot
 MOV     R1, #jit_max_fixups
 ._L2
   LDR     R2, [R0, #jit_module_fixup_table.offset]
   TEQ     R2, #0			;is slot sctive?
   ORRNE   R2, R2, #jit_fixup_persistent_flag	;YES, make persistent
   STRNE   R2, [R0, #jit_fixup_table.address]

   ADD     R0, R0, #jit_module_fixup_table.size
   SUBS    R1, R1, #1			;last slot?
 BNE     _L2				;NO

LDMFD   R13!, {R0-R2, PC}