Changeset 13687
- Timestamp:
- May 6, 2010, 10:54:15 PM (15 years ago)
- Location:
- branches/arm/lisp-kernel
- Files:
-
- 6 edited
-
ARM-notes.txt (modified) (2 diffs)
-
arm-asmutils.s (modified) (3 diffs)
-
arm-constants.s (modified) (2 diffs)
-
arm-macros.s (modified) (5 diffs)
-
arm-spentry.s (modified) (55 diffs)
-
arm-uuo.s (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/arm/lisp-kernel/ARM-notes.txt
r13663 r13687 85 85 callee-save NVRs. 86 86 87 There are some cases in the runtime where we effectively want 88 to exchange the lr with the saved lr value in a stack frame. It's 89 possible to do this with a "swp" instruction; "swp" as a means 90 of doing interlocked memory operations has been deprecated in 91 ARMv6 and later. We don't care about those semantics, and if 92 there are only a few places (calling UNWIND-PROTECT cleanup 93 forms) that need to do this it's probably better to use "swp" 94 rather than inventing a scheme that allows some register to 95 be temporarily treated as a locative. 96 97 87 98 - Subprim calls 88 99 … … 200 211 201 212 [explain complexity here ...] 213 214 215 - misc 216 217 I -hope- that the altstack mechanism works on all platforms and that 218 we don't have to explicitly check for stack overflow on r13. (If it 219 does, we probably want to check for r13 overflow in the altstack/Mach 220 fault handler and unprotect pages there.) 221 -
branches/arm/lisp-kernel/arm-asmutils.s
r13668 r13687 20 20 21 21 _beginfile 22 /* Zero R4 cache lines, starting at address in R3. Each line is assumed to be */23 /* R5 bytes wide. */24 _exportfn(C(zero_cache_lines))25 __(cmpri(cr0,r4,0))26 __(mtctr r4)27 __(beqlr)28 1:29 __(DCBZL(0,r3))30 __(add r3,r3,r5)31 __(bdnz 1b)32 __(blr)33 _endfn34 22 35 /* Flush R4 cache lines, starting at address in R3. Each line is */ 36 /* assumed to be R5 bytes wide. */ 37 _exportfn(C(flush_cache_lines)) 38 __(cmpri(cr0,r4,0)) 39 __(mtctr r4) 40 __(mr r6,r3) 41 __(beqlr) 42 1: 43 __(dcbst 0,r3) 44 __(add r3,r3,r5) 45 __(bdnz 1b) 46 __(sync) /* wait until dcbst's get to memory */ 47 __(mr r3,r6) 48 __(mtctr r4) 49 2: 50 __(icbi 0,r3) 51 __(add r3,r3,r5) 52 __(bdnz 2b) 53 __(sync) 54 __(isync) 55 __(blr) 56 /* The strange reference to "exp" is supposed to force the kernel to */ 57 /* load libm, so lisp code can use it. Under Darwin, the functionality */ 58 /* of libm is contained in libsystem, along with libc & everything else. */ 23 /* Force data from r0 to r1 into the icache */ 24 _exportfn(C(_make_data_executable)) 25 __(mov r2,#0) /* options. Pass as 0 until we know better */ 26 __(mov r12,r7) /* preserve r7 ; r12 saved by syscall */ 27 __(mov r7,0x0f0000) /* __ARM_NR_cacheflush */ 28 __(add r7,r7,#2) 29 __(svc #0) 30 __(mov r7,r12) 31 __(bx lr) 59 32 60 __ifndef(`DARWIN')61 .data62 __ifdef(`PPC64')63 .quad exp64 __else65 .long exp66 __endif67 .text68 __endif69 _endfn70 71 _exportfn(C(touch_page))72 __(str(r3,0(r3)))73 __(li r4,0)74 __(str(r4,0(r3)))75 __(li r3,1) /* can't assume that low 32 bits of r3 are non-zero */76 .globl C(touch_page_end)77 C(touch_page_end):78 __(blr)79 _endfn80 33 81 34 _exportfn(C(current_stack_pointer)) 82 __(mr r 3,sp)83 __(b lr)35 __(mr r0,sp) 36 __(bx lr) 84 37 _endfn 85 38 … … 90 43 91 44 _exportfn(C(noop)) 92 __(b lr)45 __(bx lr) 93 46 _endfn 94 47 95 _exportfn(C(set_fpscr))96 __(stru(sp,-32(sp)))97 __(stw r3,12(sp))98 __(lfd f0,8(sp))99 __(mtfsf 0xff,f0)100 __(la sp,32(sp))101 __(blr)102 _endfn103 104 105 _exportfn(C(get_fpscr))106 __(stru(sp,-32(sp)))107 __(mffs f0)108 __(stfd f0,8(sp))109 __(lwz r3,12(sp))110 __(la sp,32(sp))111 __(blr)112 _endfn113 114 48 115 49 … … 120 54 121 55 _exportfn(C(store_conditional)) 122 __(mr r6,r3) 123 1: __(lrarx(r3,0,r6)) 124 __(cmpw r3,r4) 125 __(bne- 2f) 126 __(strcx(r5,0,r6)) 127 __(bne- 1b) 128 __(isync) 129 __(blr) 130 2: __(li r0,RESERVATION_DISCHARGE) 131 __(strcx(r0,0,r0)) 132 __(blr) 56 __ifdef([LINUX]) 57 /* To deal with different ARM variants, Linux provides 58 a magic kernel function that does the right thing in 59 the absence of ldrex/strex/clrex and memory-barrier 60 functions. That function takes args in a different 61 order (r0 = expected oldval, r1 = newval, r2 = addr.) 62 */ 63 __(stmdb pc!,{r4,lr}) 64 __(eor r0,r0,r2) 65 __(eor r2,r2,r0) 66 __(eor r0,r0,r2) 67 0: __(ldr r3,[r2]) 68 __(cmp r3,r0) 69 __(bne 1f) 70 __(mov lr,#0xffff0fff) 71 __(add lr,lr,#(0xffff0fc0 - 0xffff0fff)) 72 __(blx lr) 73 __(bcc 0b) 74 1: __(mov r0,r3) 75 __(ldmia pc!,{r4,lr}) 76 __endif 133 77 _endfn 134 78 -
branches/arm/lisp-kernel/arm-constants.s
r13680 r13687 44 44 /* registers. These assignments may not be viable. */ 45 45 46 define(`arg_z',`r0') 47 define(`arg_y',`r1') 48 define(`arg_x',`r2') 49 define(`temp0',`r3') 50 define(`temp1',`r4') 51 define(`temp2',`r5') 52 define(`imm0',`r6') /* even, so ldrd/strd can use imm0/imm1 */ 53 define(`imm1',`r7') 54 define(`imm2',`r9') 55 define(`vsp',`r9') 56 define(`fn',`r10') 57 define(`rcontext',`r11') 46 define(`imm0',`r0') /* even, so ldrd/strd can use imm0/imm1 */ 47 define(`imm1',`r1') 48 define(`imm2',`r2') 49 /* rcontext = r3 can be used as an imm reg in certain contexts 50 (its value must be easily recovered, but that value never changes 51 during a thread's lifetime.) 52 */ 53 define(`rcontext',`r3') 54 define(`arg_z',`r4') 55 define(`arg_y',`r5') 56 define(`arg_x',`r6') 57 define(`temp0',`r7') 58 define(`temp1',`r8') 59 define(`temp2',`r9') 60 define(`vsp',`r10') 61 define(`fn',`r11') 58 62 define(`allocptr',`r12') 59 63 define(`sp',`r13') … … 658 662 659 663 define(`whole_reg',`temp1') 660 define(`arg_reg',`temp 3')664 define(`arg_reg',`temp0') 661 665 define(`keyvect_reg',`temp2') 662 666 define(`mask_req_start',`24') -
branches/arm/lisp-kernel/arm-macros.s
r13680 r13687 214 214 ') 215 215 216 define(`vpush_all_argregs',` 217 __(stmdb vsp!,{arg_z,arg_y,arg_x}) 218 ') 219 220 define(`vpop_all_argregs',` 221 __(ldmia vsp!,{arg_z,arg_y,arg_x}) 222 ') 223 224 216 225 217 226 /* $1 = arg/temp reg for lisp_frame_marker, $2 = value for lisp_frame.savevsp */ … … 414 423 ') 415 424 425 /* Stack-allocate an ivector; $1 = header, $0 = dnode-aligned 426 size in bytes. */ 427 define(`stack_allocate_ivector',` 428 __(str $1,[sp,-$2]!) 429 ') 430 431 416 432 /* Stack-allocate an ivector and zero its contents; caller may 417 433 change subtag of header after it's zeroed. 418 434 $1 = header (tagged as subtag_u32_vector until zeroed), $2 = dnode- 419 435 aligned size in bytes). Both $1 and $2 are modified here. */ 420 define(`stack_allocate_zeroed_ word_vector',`436 define(`stack_allocate_zeroed_ivector',` 421 437 new_macro_labels() 422 438 __(str $1,[sp,-$2]!) … … 442 458 define(`check_pending_interrupt',` 443 459 new_macro_labels() 444 __(ldr $1, tcr.tlb_pointer(rcontext))460 __(ldr $1,[rcontext,#tcr.tlb_pointer]) 445 461 __(ldr $1,[$1,$INTERRUPT_LEVEL_BINDING_INDEX]) 446 462 __(cmp $1,#0) … … 465 481 __(cmp $2,#fulltag_immheader) 466 482 __(extract_lowbyte($2,$1)) 467 __(mov $1,$1 lsr #num_subtag_bits)468 __(moveq $1,$1 lsl #2)483 __(mov $1,$1,lsr #num_subtag_bits) 484 __(moveq $1,$1,lsl #2) 469 485 __(beq macro_label(bytes)) 470 486 __(cmp $2,#max_32_bit_ivector_subtag) 471 __(movle $1,$1 lsl #2)487 __(movle $1,$1,lsl #2) 472 488 __(ble macro_label(bytes)) 473 489 __(cmp $2,#max_8_bit_ivector_subtag) … … 486 502 __(add $1,$1,$3) 487 503 ') 504 505 /* This may need to be inlined. $1=link, $2=saved sym idx, $3 = tlb, $4 = value */ 506 define(`do_unbind_to',` 507 __(ldr $1,[rcontext,#tcr.db_link]) 508 __(ldr $3,[rcontext,#tcr.tlb_pointer]) 509 1: __(ldr $2,[$1,#binding.sym]) 510 __(ldr $4,[$1,#binding.val]) 511 __(ldr $1,[$1,#binding.link]) 512 __(cmp imm0,$1) 513 __(str $4,[$3,$2]) 514 __(bne 1b) 515 __(str $1,[rcontext,#tcr.db_link]) 516 ') 517 518 /* Linux provides a weird kernel entrypoint to do cmpxchg on hardware 519 that may not support it natively. Darwin only runs on ARMv6 hardware, 520 which can use ldrex/strex instructions to do cmpxchg inline. On 521 SMP hardware, the cmpxchg should be followe by a 'dmb' (data memory 522 barrier) instruction, which is only available on ARMv7. Confused yet? 523 The Linux kernel function clobbers some registers, and we may need 524 some support in pc_luser_xp() to fix things up at interrupt/suspend 525 time. 526 Generally, imm1 = mask with exactly one bit set, *imm2 = address of 527 refbits word. */ 528 529 define(`set_ref_bit',` 530 new_macro_labels() 531 __ifdef(`LINUX') 532 .globl set_ref_bit_entry_$1 533 set_ref_bit_entry_$1: 534 __(build_lisp_frame(imm0)) /* we clobber lr */ 535 __(mov temp1,imm1) 536 __(mov temp2,rcontext) 537 macro_label(again): 538 __(ldr lr,macro_label(linux_kernel_cmpxchg)) 539 __(ldr r0,[r2]) 540 __(orr r1,r0,temp1) 541 __(blx lr) 542 .globl set_ref_bit_return_$1 543 set_ref_bit_return_$1: 544 __(mov rcontext,temp2) 545 __(ldr allocptr,[rcontext,#tcr.save_allocptr]) 546 __(bcc macro_label(again)) 547 __(restore_lisp_frame(imm0)) 548 __(b macro_label(continue)) 549 macro_label(linux_kernel_cmpxchg): 550 .word 0xffff0fc0 /* magic address */ 551 macro_label(continue): 552 __endif 553 __ifdef(`DARWIN') 554 macro_label(again): 555 __(ldrex r0,[r2]) 556 __(orr r0,r0,r1) 557 __(strex r0,r0,[r2]) 558 __(cmp r0,#0) 559 __(bne macro_label(again)) 560 __endif 561 ') 562 -
branches/arm/lisp-kernel/arm-spentry.s
r13680 r13687 46 46 ') 47 47 48 _spentry(builtin_plus) 49 __(test_two_fixnums(arg_y,arg_z,imm0)) 50 __(bne 1f) 51 __(adds arg_z,arg_y,arg_z) 52 __(bxvc lr) 53 __(b _SPfix_overflow) 54 1: 55 __(jump_builtin(_builtin_plus,2)) 56 57 _spentry(builtin_minus) 58 __(test_two_fixnums(arg_y,arg_z,imm0)) 59 __(bne 1f) 60 __(subs arg_z,arg_y,arg_z) 61 __(bxvc lr) 62 __(b _SPfix_overflow) 63 1: 64 __(jump_builtin(_builtin_minus,2)) 65 66 _spentry(builtin_times) 67 __(test_two_fixnums(arg_y,arg_z,imm0)) 68 __(bne 1f) 69 __(unbox_fixnum(imm2,arg_z)) 70 __(smull arg_z,imm1,imm2,arg_y) 71 /* Now have a "64-bit fixnum" in imm1(high) and arg_z(low). If */ 72 /* imm1 is just a sign extension of arg_z, return arg_z */ 73 __(cmp imm1,arg_z,asr #(nbits_in_word-1)) 74 __(bxeq lr) 75 /* Need to ashift the pair imm1:imm0 right fixnumshift bits */ 76 __(mov imm0,imm0,lsr #fixnumshift) 77 __(and imm2,imm1,#fixnummask) 78 __(orr imm0,imm0,imm2,lsl #(nbits_in_word-fixnumshift)) 79 __(unbox_fixnum(imm1,imm1)) 80 __(b _SPmakes64) 81 82 1: __(jump_builtin(_builtin_times,2)) 83 84 _spentry(builtin_div) 85 __(jump_builtin(_builtin_div,2)) 86 87 _spentry(builtin_eq) 88 __(test_two_fixnums(arg_y,arg_z,imm0)) 89 __(bne 1f) 90 __(cmp arg_y,arg_z) 91 __(mov arg_z,#nil_value) 92 __(addeq arg_z,arg_z,#t_offset) 93 __(bx lr) 94 1: 95 __(jump_builtin(_builtin_eq,2)) 96 97 _spentry(builtin_ne) 98 __(test_two_fixnums(arg_y,arg_z,imm0)) 99 __(bne 1f) 100 __(cmp arg_y,arg_z) 101 __(mov arg_z,#nil_value) 102 __(addne arg_z,arg_z,#t_offset) 103 __(bx lr) 104 1: 105 __(jump_builtin(_builtin_ne,2)) 106 107 _spentry(builtin_gt) 108 __(test_two_fixnums(arg_y,arg_z,imm0)) 109 __(bne 1f) 110 __(cmp arg_y,arg_z) 111 __(mov arg_z,#nil_value) 112 __(addgt arg_z,arg_z,#t_offset) 113 __(bx lr) 114 1: 115 __(jump_builtin(_builtin_gt,2)) 116 117 _spentry(builtin_ge) 118 __(test_two_fixnums(arg_y,arg_z,imm0)) 119 __(bne 1f) 120 __(cmp arg_y,arg_z) 121 __(mov arg_z,#nil_value) 122 __(addge arg_z,arg_z,#t_offset) 123 __(bx lr) 124 1: 125 __(jump_builtin(_builtin_ge,2)) 126 127 _spentry(builtin_lt) 128 __(test_two_fixnums(arg_y,arg_z,imm0)) 129 __(bne 1f) 130 __(cmp arg_y,arg_z) 131 __(mov arg_z,#nil_value) 132 __(addgt arg_z,arg_z,#t_offset) 133 __(bx lr) 134 1: 135 __(jump_builtin(_builtin_lt,2)) 136 137 _spentry(builtin_le) 138 __(test_two_fixnums(arg_y,arg_z,imm0)) 139 __(bne 1f) 140 __(cmp arg_y,arg_z) 141 __(mov arg_z,#nil_value) 142 __(addle arg_z,arg_z,#t_offset) 143 __(bx lr) 144 1: 145 __(jump_builtin(_builtin_le,2)) 146 147 _spentry(builtin_eql) 148 __(cmp arg_y,arg_z) 149 __(beq 1f) 150 __(extract_fulltag(imm0,arg_y)) 151 __(extract_fulltag(imm1,arg_z)) 152 __(cmp imm0,imm1) 153 __(bne 2f) 154 __(cmp imm0,#fulltag_misc) 155 __(bne 2f) 156 __(jump_builtin(_builtin_eql,2)) 157 1: __(mov arg_z,#nil_value) 158 __(add arg_z,arg_z,#t_offset) 159 __(bx lr) 160 2: __(mov arg_z,#nil_value) 161 __(bx lr) 162 163 _spentry(builtin_length) 164 __(extract_typecode(imm0,arg_z)) 165 __(cmp imm0,#min_vector_subtag) 166 __(ldreq arg_z,[arg_z,#vectorH.logsize]) 167 __(bxeq lr) 168 __(blo 1f) 169 __(vector_length(arg_z,arg_z,imm0)) 170 __(bx lr) 171 1: __(cmp imm0,#tag_list) 172 __(bne 8f) 173 __(mov temp2,#-1<<fixnum_shift) 174 __(mov temp0,arg_z) /* fast pointer */ 175 __(mov temp1,arg_z) /* slow pointer */ 176 2: __(cmp temp0,#nil_value) 177 __(add temp2,temp2,#fixnumone) 178 __(beq 9f) 179 __(extract_lisptag(imm0,temp0)) 180 __(cmp imm0,#tag_list) 181 __(bne 8f) 182 __(_cdr(temp0,temp0)) 183 __(tst temp2,#fixnumone) 184 __(beq 2b) 185 __(_cdr(temp1,temp1)) 186 __(cmp temp1,temp0) 187 __(bne 2b) 188 8: 189 __(jump_builtin(_builtin_length,1)) 190 9: __(mov arg_z,temp2) 191 __(bx lr) 192 193 _spentry(builtin_seqtype) 194 __(extract_typecode(imm0,arg_z)) 195 __(cmp imm0,#min_vector_subtag) 196 __(movge arg_z,#nil_value) 197 __(bxge lr) 198 __(cmp imm0,#tag_list) 199 __(moveq arg_z,#nil_value) 200 __(addeq arg_z,arg_z,#t_offset) 201 __(bxeq lr) 202 __(jump_builtin(_builtin_seqtype,1)) 203 204 /* This is usually inlined these days */ 205 _spentry(builtin_assq) 206 __(b 2f) 207 1: __(trap_unless_list(arg_z,imm0)) 208 __(_car(arg_x,arg_z)) 209 __(_cdr(arg_z,arg_z)) 210 __(cmp arg_x,#nil_value) 211 __(beq 2f) 212 __(trap_unless_list(arg_x,imm0)) 213 __(_car(temp0,arg_x)) 214 __(cmp temp0,arg_y) 215 __(bne 2f) 216 __(mov arg_z,arg_x) 217 __(bx lr) 218 2: __(cmp arg_z,#nil_value) 219 __(bne 1b) 220 __(bx lr) 221 222 _spentry(builtin_memq) 223 __(cmp arg_z,nil_value) 224 __(b 2f) 225 1: __(trap_unless_list(arg_z,imm0)) 226 __(_car(arg_x,arg_z)) 227 __(_cdr(temp0,arg_z)) 228 __(cmp arg_x,arg_y) 229 __(bxeq lr) 230 __(cmp temp0,nil_value) 231 __(mov arg_z,temp0) 232 2: __(bne 1b) 233 __(bx lr) 234 235 _spentry(builtin_logbitp) 236 /* Call out unless both fixnums,0 <= arg_y < logbitp_max_bit */ 237 __(test_two_fixnums(arg_y,arg_z,imm0)) 238 __(bne 1f) 239 __(uuo_suspend_now(al)) 240 __(cmp arg_y,#(nbits_in_word-fixnumshift)<<fixnumshift) 241 __(bhs 1f) 242 __(unbox_fixnum(imm0,arg_y)) 243 __(mov imm1,#fixnum1) 244 __(tst arg_z,imm1,lsl imm0) 245 __(mov arg_z,#nil_value) 246 __(addne arg_z,arg_z,#t_offset) 247 __(bx lr) 248 1: 249 __(jump_builtin(_builtin_logbitp,2)) 250 251 _spentry(builtin_logior) 252 __(orr imm0,arg_y,arg_z) 253 __(test_fixnum(imm0)) 254 __(moveq arg_z,imm0) 255 __(bxeq lr) 256 __(jump_builtin(_builtin_logior,2)) 257 258 _spentry(builtin_logand) 259 __(test_two_fixnums(arg_y,arg_z,imm0)) 260 __(andeq arg_z,arg_y,arg_z) 261 __(bxeq lr) 262 __(jump_builtin(_builtin_logand,2)) 263 264 _spentry(builtin_ash) 265 __(test_two_fixnums(arg_y,arg_z,imm0)) 266 __(bne 9f) 267 __(cmp arg_z,#0) 268 __(bgt 1f) 269 __(moveq arg_z,arg_y) 270 __(bxeq lr) 271 /* Shift right */ 272 __(unbox_fixnum(imm2,arg_z)) 273 __(rsb imm2,imm2,#0) 274 __(cmp imm2,#32) 275 __(movge imm2,#31) 276 __(mov arg_z,#-fixnumone) 277 __(and arg_z,arg_z,arg_y,lsr imm2) 278 __(bx lr) 279 /* shift left */ 280 1: __(unbox_fixnum(imm0,arg_y)) 281 __(unbox_fixnum(imm2,arg_z)) 282 __(cmp imm2,#32) 283 __(moveq imm1,imm0) 284 __(moveq imm0,#0) 285 __(beq _SPmakes64) 286 __(bgt 9f) 287 __(mov imm1,imm1,asl imm2) 288 __(rsb imm2,imm2,#32) 289 __(orr imm1,imm1,imm0,asr imm2) 290 __(unbox_fixnum(imm2,arg_z)) 291 __(mov imm0,imm0,asl imm2) 292 __(b _SPmake64) 293 9: 294 __(jump_builtin(_builtin_ash,2)) 295 296 _spentry(builtin_negate) 297 __(test_fixnum(arg_z)) 298 __(bne 1f) 299 __(rsbs arg_z,arg_z,#0) 300 __(bxvc lr) 301 __(b _SPfix_overflow) 302 1: 303 __(jump_builtin(_builtin_negate,1)) 304 305 _spentry(builtin_logxor) 306 __(test_two_fixnums(arg_y,arg_z,imm0)) 307 __(eoreq arg_z,arg_y,arg_z) 308 __(bxeq lr) 309 __(jump_builtin(_builtin_logxor,2)) 310 311 _spentry(builtin_aref1) 312 __(extract_typecode(imm0,arg_y)) 313 __(cmp imm0,#min_vector_subtag) 314 __(box_fixnum(arg_x,imm0)) 315 __(bgt _SPsubtag_misc_ref) 316 __(jump_builtin(_builtin_aref1,2)) 317 318 _spentry(builtin_aset1) 319 __(extract_typecode(imm0,arg_x)) 320 __(cmp imm0,#min_vector_subtag) 321 __(box_fixnum(temp0,imm0)) 322 __(bgt _SPsubtag_misc_set) 323 __(jump_builtin(_builtin_aset1,3)) 324 48 325 _spentry(jmpsym) 49 326 __(jump_fname()) … … 163 440 __(b _SPmakes32) 164 441 165 _spentry(builtin_plus) 166 __(test_two_fixnums(arg_y,arg_z,imm0)) 167 __(bne 1f) 168 __(adds arg_z,arg_y,arg_z) 169 __(bxvc lr) 170 __(b _SPfix_overflow) 171 1: 172 __(jump_builtin(_builtin_plus,2)) 173 174 _spentry(builtin_minus) 175 __(test_two_fixnums(arg_y,arg_z,imm0)) 176 __(bne 1f) 177 __(subs arg_z,arg_y,arg_z) 178 __(bxvc lr) 179 __(b _SPfix_overflow) 180 1: 181 __(jump_builtin(_builtin_minus,2)) 442 182 443 183 444 /* Construct a lisp integer out of the 64-bit unsigned value in */ … … 211 472 __(bx lr) 212 473 213 _spentry(builtin_times) 214 __(test_two_fixnums(arg_y,arg_z,imm0)) 215 __(bne 1f) 216 __(unbox_fixnum(imm2,arg_z)) 217 __(smull arg_z,imm1,imm2,arg_y) 218 /* Now have a "64-bit fixnum" in imm1(high) and arg_z(low). If */ 219 /* imm1 is just a sign extension of arg_z, return arg_z */ 220 __(cmp imm1,arg_z,asr #(nbits_in_word-1)) 221 __(bxeq lr) 222 /* Need to ashift the pair imm1:imm0 right fixnumshift bits */ 223 __(mov imm0,imm0,lsr #fixnumshift) 224 __(and imm2,imm1,#fixnummask) 225 __(orr imm0,imm0,imm2,lsl #(nbits_in_word-fixnumshift)) 226 __(unbox_fixnum(imm1,imm1)) 227 __(b _SPmakes64) 228 229 1: __(jump_builtin(_builtin_times,2)) 230 231 _spentry(builtin_eq) 232 __(test_two_fixnums(arg_y,arg_z,imm0)) 233 __(bne 1f) 234 __(cmp arg_y,arg_z) 235 __(mov arg_z,#nil_value) 236 __(addeq arg_z,arg_z,#t_offset) 237 __(bx lr) 238 1: 239 __(jump_builtin(_builtin_eq,2)) 240 241 _spentry(builtin_ne) 242 __(test_two_fixnums(arg_y,arg_z,imm0)) 243 __(bne 1f) 244 __(cmp arg_y,arg_z) 245 __(mov arg_z,#nil_value) 246 __(addne arg_z,arg_z,#t_offset) 247 __(bx lr) 248 1: 249 __(jump_builtin(_builtin_ne,2)) 250 251 _spentry(builtin_gt) 252 __(test_two_fixnums(arg_y,arg_z,imm0)) 253 __(bne 1f) 254 __(cmp arg_y,arg_z) 255 __(mov arg_z,#nil_value) 256 __(addgt arg_z,arg_z,#t_offset) 257 __(bx lr) 258 1: 259 __(jump_builtin(_builtin_gt,2)) 260 261 _spentry(builtin_ge) 262 __(test_two_fixnums(arg_y,arg_z,imm0)) 263 __(bne 1f) 264 __(cmp arg_y,arg_z) 265 __(mov arg_z,#nil_value) 266 __(addge arg_z,arg_z,#t_offset) 267 __(bx lr) 268 1: 269 __(jump_builtin(_builtin_ge,2)) 270 271 _spentry(builtin_lt) 272 __(test_two_fixnums(arg_y,arg_z,imm0)) 273 __(bne 1f) 274 __(cmp arg_y,arg_z) 275 __(mov arg_z,#nil_value) 276 __(addgt arg_z,arg_z,#t_offset) 277 __(bx lr) 278 1: 279 __(jump_builtin(_builtin_lt,2)) 280 281 _spentry(builtin_le) 282 __(test_two_fixnums(arg_y,arg_z,imm0)) 283 __(bne 1f) 284 __(cmp arg_y,arg_z) 285 __(mov arg_z,#nil_value) 286 __(addle arg_z,arg_z,#t_offset) 287 __(bx lr) 288 1: 289 __(jump_builtin(_builtin_le,2)) 474 475 476 477 290 478 291 479 /* funcall nfn, returning multiple values if it does. */ … … 365 553 __(b local_label(return_values)) 366 554 367 dnl /* Caller has pushed tag and 0 or more values; nargs = nvalues. */ 368 dnl /* Otherwise, process unwind-protects and throw to indicated catch frame. */ 369 dnl 370 dnl _spentry(throw) 371 dnl __(ldr imm1,[rcontext, #tcr.catch_top]) 372 dnl __(mov imm0,#0) /* count intervening catch/unwind-protect frames. */ 373 dnl __(cmpri(cr0,imm1,0)) 374 dnl __(ldr temp0,[vsp,nargs]) 375 dnl __(beq- cr0,local_label(_throw_tag_not_found)) 376 dnl local_label(_throw_loop): 377 dnl __(ldr temp1,[imm1,#catch_frame.catch_tag]) 378 dnl __(cmpr(cr0,temp0,temp1)) 379 dnl __(mov imm2,imm1) 380 dnl __(ldr imm1,[imm1,#catch_frame.link]) 381 dnl __(cmpri(cr1,imm1,0)) 382 dnl __(beq cr0,local_label(_throw_found)) 383 dnl __(addi imm0,imm0,fixnum_one) 384 dnl __(beq- cr1,local_label(_throw_tag_not_found)) 385 dnl __(b local_label(_throw_loop)) 386 dnl /* imm2: (tstack-consed) target catch frame, imm0: count of intervening */ 387 dnl /* frames. If target isn't a multiple-value receiver, discard extra values */ 388 dnl /* (less hair, maybe.) */ 389 dnl local_label(_throw_found): 390 dnl __(ldr imm1,[imm2,#catch_frame.mvflag]) 391 dnl __(cmpri(cr0,imm1,0)) 392 dnl __(cmpri(cr1,nargs,0)) 393 dnl __(mov fn,#0) 394 dnl __(add imm1,vsp,nargs) 395 dnl __(add imm1,[imm1,#-node_size]) 396 dnl __(bne cr0,local_label(_throw_all_values)) 397 dnl __(set_nargs(1)) 398 dnl __(beq cr1,local_label(_throw_default_1_val)) 399 dnl __(mov vsp,imm1) 400 dnl __(b local_label(_throw_all_values)) 401 dnl local_label(_throw_default_1_val): 402 dnl __(mov imm4,#nil_value) 403 dnl __(vpush1(imm4)) 404 dnl local_label(_throw_all_values): 405 dnl __(bl _SPnthrowvalues) 406 dnl __(ldr imm3,[rcontext,#tcr.catch_top]) 407 dnl __(ldr imm1,[rcontext,#tcr.db_link]) 408 dnl __(ldr imm0,[imm3,#catch_frame.db_link]) 409 dnl __(ldr imm4,[imm3,#catch_frame.mvflag]) 410 dnl __(cmpr(cr0,imm0,imm1)) 411 dnl __(cmpri(cr1,imm4,0)) 412 dnl __(add tsp,[imm3,#-((tsp_frame.fixed_overhead+fulltag_misc))]) 413 dnl __(beq cr0,local_label(_throw_dont_unbind)) 414 dnl __(bl _SPunbind_to) 415 dnl local_label(_throw_dont_unbind): 416 dnl __(add imm0,vsp,nargs) 417 dnl __(cmpri(cr0,nargs,0)) 418 dnl __(ldr imm1,[imm3,#catch_frame.csp]) 419 dnl __(ldr imm1,[imm1,#lisp_frame.savevsp]) 420 dnl __(bne cr1,local_label(_throw_multiple)) 421 dnl /* Catcher expects single value in arg_z */ 422 dnl __(ldr arg_z,[imm0,#-node_size]) 423 dnl __(b local_label(_throw_pushed_values)) 424 dnl local_label(_throw_multiple): 425 dnl __(beq cr0,local_label(_throw_pushed_values)) 426 dnl __(mov imm2,nargs) 427 dnl local_label(_throw_mvloop): 428 dnl __(subi imm2,imm2,fixnum_one) 429 dnl __(cmpri(imm2,0)) 430 dnl __(ldru(temp0,-node_size(imm0))) 431 dnl __(push(temp0,imm1)) 432 dnl __(bgt local_label(_throw_mvloop)) 433 dnl local_label(_throw_pushed_values): 434 dnl __(mov vsp,imm1) 435 dnl __(ldr imm1,[imm3,#catch_frame.xframe]) 436 dnl __(str(imm1,tcr.xframe(rcontext))) 437 dnl __(ldr sp,[imm3,#catch_frame.csp]) 438 dnl __(ldr fn,[sp,#lisp_frame.savefn]) 439 dnl __(ldr loc_pc,[sp,#lisp_frame.savelr]) 440 dnl __(discard_lisp_frame()) 441 dnl __(mtlr loc_pc) 442 dnl __(restore_catch_nvrs(imm3)) 443 dnl __(ldr imm3,[imm3,#catch_frame.link]) 444 dnl __(str(imm3,tcr.catch_top(rcontext))) 445 dnl __(unlink(tsp)) 446 dnl __(bx lr) 447 dnl local_label(_throw_tag_not_found): 448 dnl __(uuo_interr(error_throw_tag_missing,temp0)) 449 dnl __(strux(temp0,vsp,nargs)) 450 dnl __(b _SPthrow) 451 dnl 452 dnl 453 dnl /* This takes N multiple values atop the vstack. */ 454 dnl _spentry(nthrowvalues) 555 /* Caller has pushed tag and 0 or more values; nargs = nvalues. */ 556 /* Otherwise, process unwind-protects and throw to indicated catch frame. */ 557 558 559 _spentry(throw) 560 __(ldr imm1,[rcontext, #tcr.catch_top]) 561 __(mov imm0,#0) /* count intervening catch/unwind-protect frames. */ 562 __(cmp imm1,#0) 563 __(ldr temp0,[vsp,nargs]) 564 __(beq local_label(_throw_tag_not_found)) 565 local_label(_throw_loop): 566 __(ldr temp1,[imm1,#catch_frame.catch_tag]) 567 __(cmp temp0,temp1) 568 __(mov imm2,imm1) 569 __(ldr imm1,[imm1,#catch_frame.link]) 570 __(beq C(_throw_found)) 571 __(cmp imm1,#0) 572 __(add imm0,imm0,#fixnum_one) 573 __(bne local_label(_throw_loop)) 574 local_label(_throw_tag_not_found): 575 __(uuo_error_no_throw_tag(al,temp0)) 576 __(str temp0,[vsp,nargs]) 577 __(b _SPthrow) 578 579 /* This takes N multiple values atop the vstack. */ 580 _spentry(nthrowvalues) 455 581 dnl __(mov imm1,#1) 456 582 dnl __(mov imm4,imm0) … … 464 590 dnl __(ldr imm0,[temp0,#catch_frame.db_link]) 465 591 dnl __(ldr imm3,[temp0,#catch_frame.link]) 466 dnl __(cmpr( cr0,imm0,imm1))592 dnl __(cmpr(imm0,imm1)) 467 593 dnl __(str(imm3,tcr.catch_top(rcontext))) 468 594 dnl __(ldr temp1,[temp0,#catch_frame.catch_tag]) … … 471 597 dnl __(str(first_nvr,tcr.xframe(rcontext))) 472 598 dnl __(ldr sp,[temp0,#catch_frame.csp]) 473 dnl __(beq cr0,local_label(_nthrowv_dont_unbind))599 dnl __(beq local_label(_nthrowv_dont_unbind)) 474 600 dnl __(mflr loc_pc) 475 601 dnl __(bl _SPunbind_to) … … 488 614 dnl __(push(temp1,imm0)) 489 615 dnl local_label(_nthrowv_push_test): 490 dnl __(cmp ri(imm2,0))616 dnl __(cmp imm2,#0)) 491 617 dnl __(subi imm2,imm2,fixnum_one) 492 618 dnl __(bne local_label(_nthrowv_push_loop)) … … 529 655 dnl __(subi imm2,imm2,fixnum_one) 530 656 dnl local_label(_nthrowv_tpushtest): 531 dnl __(cmp ri(imm2,0))657 dnl __(cmp imm2,#0) 532 658 dnl __(bne local_label(_nthrowv_tpushloop)) 533 659 dnl __(stru(imm4,node_size(imm0))) … … 553 679 dnl __(subi imm2,imm2,fixnum_one) 554 680 dnl local_label(_nthrowv_tpoptest): 555 dnl __(cmp ri(imm2,0))681 dnl __(cmp imm2,#0) 556 682 dnl __(bne local_label(_nthrowv_tpoploop)) 557 683 dnl __(ldr imm4,[imm0,#node_size]) … … 567 693 dnl __(mov nargs,imm4) 568 694 dnl __(bx lr) 569 dnl 570 dnl /* This is a (slight) optimization. When running an unwind-protect, */ 571 dnl /* save the single value and the throw count in the tstack frame. */ 572 dnl /* Note that this takes a single value in arg_z. */ 573 dnl _spentry(nthrow1value) 574 dnl __(mov imm1,#1) 575 dnl __(mov imm4,imm0) 576 dnl __(str(imm1,tcr.unwinding(rcontext))) 577 dnl local_label(_nthrow1v_nextframe): 578 dnl __(subi imm4,imm4,fixnum_one) 579 dnl __(cmpri(cr1,imm4,0)) 580 dnl __(ldr temp0,[rcontext,#tcr.catch_top]) 581 dnl __(ldr imm1,[rcontext,#tcr.db_link]) 582 dnl __(set_nargs(1)) 583 dnl __(blt cr1,local_label(_nthrow1v_done)) 584 dnl __(ldr imm3,[temp0,#catch_frame.link]) 585 dnl __(ldr imm0,[temp0,#catch_frame.db_link]) 586 dnl __(cmpr(cr0,imm0,imm1)) 587 dnl __(str(imm3,tcr.catch_top(rcontext))) 588 dnl __(ldr imm3,[temp0,#catch_frame.xframe]) 589 dnl __(ldr temp1,[temp0,#catch_frame.catch_tag]) 590 dnl __(cmpri(cr7,temp1,unbound_marker)) /* unwind-protect ? */ 591 dnl __(str(imm3,tcr.xframe(rcontext))) 592 dnl __(ldr sp,[temp0,#catch_frame.csp]) 593 dnl __(beq cr0,local_label(_nthrow1v_dont_unbind)) 594 dnl __(mflr loc_pc) 595 dnl __(bl _SPunbind_to) 596 dnl __(mtlr loc_pc) 597 dnl local_label(_nthrow1v_dont_unbind): 598 dnl __(beq cr7,local_label(_nthrow1v_do_unwind)) 599 dnl /* A catch frame. If the last one, restore context from there. */ 600 dnl __(bne cr1,local_label(_nthrow1v_skip)) 601 dnl __(ldr vsp,[sp,#lisp_frame.savevsp]) 602 dnl __(restore_catch_nvrs(temp0)) 603 dnl local_label(_nthrow1v_skip): 604 dnl __(la tsp,-(tsp_frame.fixed_overhead+fulltag_misc)(temp0)) 605 dnl __(unlink(tsp)) 606 dnl __(discard_lisp_frame()) 607 dnl __(b local_label(_nthrow1v_nextframe)) 608 dnl local_label(_nthrow1v_do_unwind): 609 dnl /* This is harder, but not as hard (not as much BLTing) as the */ 610 dnl /* multiple-value case. */ 611 dnl /* Save our caller's LR and FN in the csp frame created by the unwind- */ 612 dnl /* protect. (Clever, eh ?) */ 613 dnl 614 dnl __(restore_catch_nvrs(temp0)) 615 dnl __(la tsp,-(tsp_frame.fixed_overhead+fulltag_misc)(temp0)) 616 dnl __(unlink(tsp)) 617 dnl __(ldr loc_pc,[sp,#lisp_frame.savelr]) 618 dnl __(ldr nfn,[sp,#lisp_frame.savefn]) 619 dnl __(mtctr loc_pc) /* cleanup code address. */ 620 dnl __(str(fn,lisp_frame.savefn(sp))) 621 dnl __(mflr loc_pc) 622 dnl __(mov fn,nfn) 623 dnl __(str(loc_pc,lisp_frame.savelr(sp))) 624 dnl __(TSP_Alloc_Fixed_Boxed(2*node_size)) /* tsp overhead, value, throw count */ 625 dnl __(str(arg_z,tsp_frame.data_offset(tsp))) 626 dnl __(str(imm4,tsp_frame.data_offset+node_size(tsp))) 627 dnl __(ldr vsp,[sp,#lisp_frame.savevsp]) 628 dnl __(str(rzero,tcr.unwinding(rcontext))) 629 dnl __(bctrl) 630 dnl __(mov imm1,#1) 631 dnl __(ldr arg_z,[tsp,#tsp_frame.data_offset]) 632 dnl __(str(imm1,tcr.unwinding(rcontext))) 633 dnl __(ldr imm4,[tsp,#tsp_frame.data_offset+node_size]) 634 dnl __(ldr fn,[sp,#lisp_frame.savefn]) 635 dnl __(ldr loc_pc,[sp,#lisp_frame.savelr]) 636 dnl __(discard_lisp_frame()) 637 dnl __(mtlr loc_pc) 638 dnl __(unlink(tsp)) 639 dnl __(b local_label(_nthrow1v_nextframe)) 640 dnl local_label(_nthrow1v_done): 641 dnl __(str(rzero,tcr.unwinding(rcontext))) 642 dnl /* nargs has an undefined value here, so we can clobber it while */ 643 dnl /* polling for a deferred interrupt */ 644 dnl __(check_pending_interrupt()) 645 dnl __(bx lr) 695 696 /* This is a (slight) optimization. When running an unwind-protect, */ 697 /* save the single value and the throw count in the tstack frame. */ 698 /* Note that this takes a single value in arg_z. */ 699 _spentry(nthrow1value) 700 __(mov imm1,#1) 701 __(mov temp2,imm0) 702 __(str imm1,[rcontext,#tcr.unwinding]) 703 __(b C(nthrow1v)) 704 646 705 647 706 /* arg_z = symbol: bind it to its current value */ … … 700 759 __(set_nargs(2)) 701 760 __(b _SPksignalerr) 702 dnl 703 dnl 704 dnl /* The function pc_luser_xp() - which is used to ensure that suspended threads */ 705 dnl /* are suspended in a GC-safe way - has to treat these subprims (which */ 706 dnl /* implement the EGC write-barrier) specially. Specifically, a store that */ 707 dnl /* might introduce an intergenerational reference (a young pointer stored */ 708 dnl /* in an old object) has to "memoize" that reference by setting a bit in */ 709 dnl /* the global "refbits" bitmap. */ 710 dnl /* This has to happen atomically, and has to happen atomically wrt GC. */ 711 dnl /* Note that updating a word in a bitmap is itself not atomic, unless we use */ 712 dnl /* interlocked loads and stores. */ 713 dnl 714 dnl 715 dnl /* For RPLACA and RPLACD, things are fairly simple: regardless of where we */ 716 dnl /* are in the function, we can do the store (even if it's already been done) */ 717 dnl /* and calculate whether or not we need to set the bit out-of-line. (Actually */ 718 dnl /* setting the bit needs to be done atomically, unless we're sure that other */ 719 dnl /* threads are suspended.) */ 720 dnl /* We can unconditionally set the suspended thread's PC to its LR. */ 721 dnl 722 dnl .globl C(egc_write_barrier_start) 723 dnl _spentry(rplaca) 724 dnl C(egc_write_barrier_start): 725 dnl __(cmplr(cr2,arg_z,arg_y)) 726 dnl __(_rplaca(arg_y,arg_z)) 727 dnl __(blelr cr2) 728 dnl __(ref_global(imm2,ref_base)) 729 dnl __(sub imm0,arg_y,imm2) 730 dnl __(load_highbit(imm3)) 731 dnl __(srri(imm0,imm0,dnode_shift)) 732 dnl __(ref_global(imm1,oldspace_dnode_count)) 733 dnl __(extract_bit_shift_count(imm4,imm0)) 734 dnl __(cmplr(imm0,imm1)) 735 dnl __(srr(imm3,imm3,imm4)) 736 dnl __(srri(imm0,imm0,bitmap_shift)) 737 dnl __(ref_global(imm2,refbits)) 738 dnl __(bgelr) 739 dnl __(slri(imm0,imm0,word_shift)) 740 dnl __(ldr imm1,[imm2,imm0]) 741 dnl __(and. imm1,imm1,imm3) 742 dnl __(bnelr) 743 dnl 1: __(lrarx(imm1,imm2,imm0)) 744 dnl __(or imm1,imm1,imm3) 745 dnl __(strcx(imm1,imm2,imm0)) 746 dnl __(bne- 1b) 747 dnl __(isync) 748 dnl __(bx lr) 749 dnl 750 dnl .globl C(egc_rplacd) 751 dnl _spentry(rplacd) 752 dnl C(egc_rplacd): 753 dnl __(cmplr(cr2,arg_z,arg_y)) 754 dnl __(_rplacd(arg_y,arg_z)) 755 dnl __(blelr cr2) 756 dnl __(ref_global(imm2,ref_base)) 757 dnl __(sub imm0,arg_y,imm2) 758 dnl __(load_highbit(imm3)) 759 dnl __(srri(imm0,imm0,dnode_shift)) 760 dnl __(ref_global(imm1,oldspace_dnode_count)) 761 dnl __(extract_bit_shift_count(imm4,imm0)) 762 dnl __(cmplr(imm0,imm1)) 763 dnl __(srr(imm3,imm3,imm4)) 764 dnl __(srri(imm0,imm0,bitmap_shift)) 765 dnl __(ref_global(imm2,refbits)) 766 dnl __(bgelr) 767 dnl __(slri(imm0,imm0,word_shift)) 768 dnl __(ldr imm1,[imm2,imm0]) 769 dnl __(and. imm1,imm1,imm3) 770 dnl __(bnelr) 771 dnl 1: __(lrarx(imm1,imm2,imm0)) 772 dnl __(or imm1,imm1,imm3) 773 dnl __(strcx(imm1,imm2,imm0)) 774 dnl __(bne- 1b) 775 dnl __(isync) 776 dnl __(bx lr) 777 dnl 761 762 763 /* The function pc_luser_xp() - which is used to ensure that suspended threads */ 764 /* are suspended in a GC-safe way - has to treat these subprims (which */ 765 /* implement the EGC write-barrier) specially. Specifically, a store that */ 766 /* might introduce an intergenerational reference (a young pointer stored */ 767 /* in an old object) has to "memoize" that reference by setting a bit in */ 768 /* the global "refbits" bitmap. */ 769 /* This has to happen atomically, and has to happen atomically wrt GC. */ 770 /* Note that updating a word in a bitmap is itself not atomic, unless we use */ 771 /* interlocked loads and stores. */ 772 773 774 /* For RPLACA and RPLACD, things are fairly simple: regardless of where we */ 775 /* are in the function, we can do the store (even if it's already been done) */ 776 /* and calculate whether or not we need to set the bit out-of-line. (Actually */ 777 /* setting the bit needs to be done atomically, unless we're sure that other */ 778 /* threads are suspended.) */ 779 /* We can unconditionally set the suspended thread's PC to its LR. */ 780 781 .globl C(egc_write_barrier_start) 782 _spentry(rplaca) 783 C(egc_write_barrier_start): 784 __(cmp arg_z,arg_y) 785 __(_rplaca(arg_y,arg_z)) 786 __(bxls lr) 787 __(ref_global(temp0,ref_base)) 788 __(sub imm0,arg_y,temp0) 789 __(mov imm0,imm0,lsr #dnode_shift) 790 __(ref_global(temp0,oldspace_dnode_count)) 791 __(cmp imm0,temp0) 792 __(bxhs lr) 793 __(and imm2,imm0,#31) 794 __(mov imm1,#0x80000000) 795 __(mov imm1,imm1,lsr imm2) 796 __(mov imm0,imm0,lsr #bitmap_shift) 797 __(ref_global(imm2,refbits)) 798 __(add imm2,imm2,imm0,lsl #word_shift) 799 __(ldr imm0,[imm2]) 800 __(ands imm0,imm0,imm1) 801 __(bxne lr) 802 __(build_lisp_frame(imm0)) 803 __(set_ref_bit(rplaca)) 804 __(bx lr) 805 806 807 .globl C(egc_rplacd) 808 _spentry(rplacd) 809 C(egc_rplacd): 810 __(cmp arg_z,arg_y) 811 __(_rplacd(arg_y,arg_z)) 812 __(bxls lr) 813 __(ref_global(temp0,ref_base)) 814 __(sub imm0,arg_y,temp0) 815 __(mov imm0,imm0,lsr #dnode_shift) 816 __(ref_global(temp0,oldspace_dnode_count)) 817 __(cmp imm0,temp0) 818 __(bxhs lr) 819 __(and imm2,imm0,#31) 820 __(mov imm1,#0x80000000) 821 __(mov imm1,imm1,lsr imm2) 822 __(mov imm0,imm0,lsr #bitmap_shift) 823 __(ref_global(imm2,refbits)) 824 __(add imm2,imm2,imm0,lsl #word_shift) 825 __(ldr imm0,[imm2]) 826 __(ands imm0,imm0,imm1) 827 __(bxne lr) 828 __(build_lisp_frame(imm0)) 829 __(set_ref_bit(rplacd)) 830 __(bx lr) 831 832 778 833 /* Storing into a gvector can be handled the same way as storing into a CONS. */ 779 834 … … 781 836 _spentry(gvset) 782 837 C(egc_gvset): 783 dnl __(cmplr(cr2,arg_z,arg_x))838 __(cmp arg_z,arg_x) 784 839 __(add imm0,arg_y,#misc_data_offset) 785 840 __(str arg_z,[arg_x,imm0]) 786 __(bx lr) 787 dnl __(blelr cr2) 788 dnl __(add imm0,imm0,arg_x) 789 dnl __(ref_global(imm2,ref_base)) 790 dnl __(load_highbit(imm3)) 791 dnl __(ref_global(imm1,oldspace_dnode_count)) 792 dnl __(sub imm0,imm0,imm2) 793 dnl __(srri(imm0,imm0,dnode_shift)) 794 dnl __(cmplr(imm0,imm1)) 795 dnl __(extract_bit_shift_count(imm4,imm0)) 796 dnl __(srri(imm0,imm0,bitmap_shift)) 797 dnl __(srr(imm3,imm3,imm4)) 798 dnl __(ref_global(imm2,refbits)) 799 dnl __(bgelr) 800 dnl __(slri(imm0,imm0,word_shift)) 801 dnl __(ldrx(imm1,imm2,imm0)) 802 dnl __(and. imm1,imm1,imm3) 803 dnl __(bnelr) 804 dnl 1: __(lrarx(imm1,imm2,imm0)) 805 dnl __(or imm1,imm1,imm3) 806 dnl __(strcx(imm1,imm2,imm0)) 807 dnl __(bne- 1b) 808 dnl __(isync) 809 dnl __(bx lr) 810 dnl 841 __(bxls lr) 842 __(add imm0,imm0,arg_x) 843 __(ref_global(temp0,ref_base)) 844 __(sub imm0,imm0,temp0) 845 __(mov imm0,imm0,lsr #dnode_shift) 846 __(ref_global(temp0,oldspace_dnode_count)) 847 __(cmp imm0,temp0) 848 __(bxhs lr) 849 __(and imm2,imm0,#31) 850 __(mov imm1,#0x80000000) 851 __(mov imm1,imm1,lsr imm2) 852 __(mov imm0,imm0,lsr #bitmap_shift) 853 __(ref_global(imm2,refbits)) 854 __(add imm2,imm2,imm0,lsl #word_shift) 855 __(ldr imm0,[imm2]) 856 __(ands imm0,imm0,imm1) 857 __(bxne lr) 858 __(build_lisp_frame(imm0)) 859 __(set_ref_bit(gvset)) 860 __(bx lr) 861 862 811 863 dnl /* This is a special case of storing into a gvector: if we need to memoize */ 812 864 dnl /* the store, record the address of the hash-table vector in the refmap, */ … … 987 1039 __(mov imm0,temp2,lsl #num_subtag_bits-word_shift) 988 1040 __(orr imm0,imm0,#subtag_u32_vector) 989 __(stack_allocate_zeroed_ word_vector(imm0,temp2))1041 __(stack_allocate_zeroed_ivector(imm0,temp2)) 990 1042 __(mov imm0,#subtag_simple_vector) 991 1043 __(strb imm0,[sp,#0]) … … 1014 1066 __(mov imm0,nargs,lsl #num_subtag_bits-fixnumshift) 1015 1067 __(orr imm0,imm0,#subtag_u32_vector) 1016 __(stack_allocate_zeroed_ word_vector(imm0,imm1))1068 __(stack_allocate_zeroed_ivector(imm0,imm1)) 1017 1069 __(mov imm0,#subtag_simple_vector) 1018 1070 __(strb imm0,[sp,#0]) … … 1043 1095 dnl /* but it's better to check now than to crash later. */ 1044 1096 dnl 1045 dnl __(cmp ri(arg_z,nil_value))1097 dnl __(cmp arg_z,#nil_value) 1046 1098 dnl __(mov arg_x,arg_z) /* fast */ 1047 1099 dnl __(mov temp1,arg_z) /* slow */ … … 1067 1119 dnl __(mov arg_x,arg_y) 1068 1120 dnl 1: 1069 dnl __(cmp ri(cr0,arg_x,nil_value))1121 dnl __(cmp arg_x,#nil_value) 1070 1122 dnl __(la imm0,node_size(imm0)) 1071 1123 dnl __(_cdr(arg_x,arg_x)) … … 1074 1126 dnl /* Determine word count, add 1 (to align), and make room. */ 1075 1127 dnl /* if count is 0, make an empty tsp frame and exit */ 1076 dnl __(cmp ri(cr0,imm0,0))1128 dnl __(cmp imm0,#0) 1077 1129 dnl __(add imm1,imm0,imm0) 1078 1130 dnl __(add imm1,imm1,imm0) 1079 1131 dnl __(dnode_align(imm1,imm1,node_size)) 1080 dnl __(bne+ cr0,2f)1132 dnl __(bne+ 2f) 1081 1133 dnl __(TSP_Alloc_Fixed_Boxed(2*node_size)) 1082 1134 dnl __(bx lr) … … 1097 1149 dnl __(ldr imm4,[rcontext,#tcr.tlb_pointer]) /* Need to reload after trap */ 1098 1150 dnl __(ldrx(temp3,imm4,imm0)) 1099 dnl __(cmp ri(cr0,arg_x,nil_value))1151 dnl __(cmp arg_x,#nil_value) 1100 1152 dnl __(mov temp2,#unbound_marker) 1101 1153 dnl __(beq cr1,4f) … … 1107 1159 dnl __(str temp2,imm4,imm0) 1108 1160 dnl __(mov imm1,imm2) 1109 dnl __(bne cr0,3b)1161 dnl __(bne 3b) 1110 1162 dnl __(str(imm2,tcr.db_link(rcontext))) 1111 1163 dnl __(bx lr) … … 1127 1179 __(mov imm0,#subtag_u32_vector) 1128 1180 __(orr imm0,imm0,arg_y,lsl #num_subtag_bits-fixnumshift) 1129 __(stack_allocate_zeroed_ word_vector(imm0,imm1))1181 __(stack_allocate_zeroed_ivector(imm0,imm1)) 1130 1182 __(unbox_fixnum(imm0,arg_z)) 1131 1183 __(strb imm0,[sp]) … … 1151 1203 __(cmp imm1,#stack_alloc_limit) 1152 1204 __(bhs 9f) 1153 __(stack_allocate_zeroed_ word_vector(imm0,imm1))1205 __(stack_allocate_zeroed_ivector(imm0,imm1)) 1154 1206 __(add arg_z,sp,#fulltag_misc) 1155 1207 __(bx lr) … … 1234 1286 __(bx lr) 1235 1287 1236 dnl /* Indicate whether &optional arguments were actually supplied. nargs */ 1237 dnl /* contains the actual arg count (minus the number of required args); */ 1238 dnl /* imm0 contains the number of &optional args in the lambda list. */ 1239 dnl /* Note that nargs may be > imm0 if &rest/&key is involved. */ 1240 dnl _spentry(opt_supplied_p) 1241 dnl __(mov imm1,#0) 1242 dnl 1: 1243 dnl /* (vpush (< imm1 nargs)) */ 1244 dnl __(xor imm2,imm1,nargs) 1245 dnl __(srawi imm2,imm2,31) 1246 dnl __(or imm2,imm2,imm1) 1247 dnl __(addi imm1,imm1,#fixnumone) 1248 dnl __(cmpr(cr0,imm1,imm0)) 1249 dnl __(subf imm2,nargs,imm2) 1250 dnl __(srwi imm2,imm2,31) 1251 dnl __(insrwi imm2,imm2,1,27) 1252 dnl __(addi imm2,imm2,nil_value) 1253 dnl __(vpush1(imm2)) 1254 dnl __(bne cr0,1b) 1255 dnl __(bx lr) 1256 dnl 1257 dnl 1258 dnl 1288 /* Indicate whether &optional arguments were actually supplied. nargs */ 1289 /* contains the actual arg count (minus the number of required args); */ 1290 /* imm0 contains the number of &optional args in the lambda list. */ 1291 /* Note that nargs may be > imm0 if &rest/&key is involved. */ 1292 _spentry(opt_supplied_p) 1293 __(mov imm1,#0) 1294 __(mov arg_x,#nil_value) 1295 __(add arg_x,arg_x,#t_offset) 1296 1: 1297 /* (vpush (< imm1 nargs)) */ 1298 __(cmp imm1,nargs) 1299 __(subeq imm1,imm1,#t_offset) 1300 __(vpush1(imm1)) 1301 __(cmp imm1,imm0) 1302 __(bne 1b) 1303 __(bx lr) 1304 1259 1305 /* Cons a list of length nargs and vpush it. */ 1260 1306 /* Use this entry point to heap-cons a simple &rest arg. */ … … 1304 1350 __(vpush1(arg_z)) 1305 1351 __(bx lr) 1306 dnl 1307 dnl 1352 1353 1308 1354 dnl _spentry(simple_keywords) 1309 1355 dnl __(mov imm0,#0) … … 1345 1391 dnl /* So, the number of args pushed so far is the larger of nargs */ 1346 1392 dnl /* and the (canonical) total of required/&optional args received. */ 1347 dnl __(cmpr( cr0,nargs,imm0))1393 dnl __(cmpr(nargs,imm0)) 1348 1394 dnl __(add arg_z,vsp,nargs) 1349 dnl __(bge+ cr0,1f)1395 dnl __(bge+ 1f) 1350 1396 dnl __(add arg_z,vsp,imm0) 1351 1397 dnl 1: … … 1358 1404 dnl /* If there aren't any such pairs, the first step is the last */ 1359 1405 dnl /* step. */ 1360 dnl __(cmp ri(cr0,imm3,0))1406 dnl __(cmp imm3,#0) 1361 1407 dnl __(mov arg_z,#0) 1362 1408 dnl __(sub imm1,nargs,imm0) … … 1366 1412 dnl 2: 1367 1413 dnl __(addi arg_z,arg_z,fixnum_one) 1368 dnl __(cmplr( cr0,arg_z,imm3))1414 dnl __(cmplr(arg_z,imm3)) 1369 1415 dnl __(mov imm5,#nil_value) 1370 1416 dnl __(vpush1(imm5)) 1371 1417 dnl __(vpush1(imm5)) 1372 1418 dnl 3: 1373 dnl __(bne cr0,2b)1419 dnl __(bne 2b) 1374 1420 dnl __(andi. arg_z,imm1,fixnum_one) 1375 1421 dnl __(blelr cr1) /* no keyword/value pairs to consider. */ 1376 dnl __(bne cr0,odd_keywords)1422 dnl __(bne odd_keywords) 1377 1423 dnl /* We have key/value pairs. Move them to the top of the vstack, */ 1378 1424 dnl /* then set the value/supplied-p vars to NIL. */ … … 1393 1439 dnl __(mov imm4,#nil_value) 1394 1440 dnl __(subi arg_z,arg_z,2<<fixnumshift) 1395 dnl __(cmplri( cr0,arg_z,0))1441 dnl __(cmplri(arg_z,0)) 1396 1442 dnl __(ldr arg_x,[varptr,#node_size*0]) 1397 1443 dnl __(ldr arg_y,[varptr,#node_size*1]) … … 1402 1448 dnl __(str(arg_y,node_size*1(valptr))) 1403 1449 dnl __(la valptr,node_size*2(valptr)) 1404 dnl __(bne cr0,4b)1450 dnl __(bne 4b) 1405 1451 dnl 1406 1452 dnl … … 1416 1462 dnl __(mov imm4,valptr) 1417 1463 dnl 5: 1418 dnl __(cmpri( cr0,keyword_flags,16<<fixnumshift)) /* seen :a-o-k yet ? */1464 dnl __(cmpri(keyword_flags,16<<fixnumshift)) /* seen :a-o-k yet ? */ 1419 1465 dnl __(ldru(arg_z,-node_size(valptr))) 1420 1466 dnl __(ldru(arg_y,-node_size(valptr))) … … 1425 1471 dnl __(cmpr(cr7,valptr,limit)) 1426 1472 dnl __(bne cr6,6f) 1427 dnl __(bge cr0,6f) /* Already seen :allow-other-keys */1473 dnl __(bge 6f) /* Already seen :allow-other-keys */ 1428 1474 dnl __(ori keyword_flags,keyword_flags,16<<fixnumshift) 1429 1475 dnl __(beq cr1,6f) … … 1438 1484 dnl __(cmpr(cr1,imm0,imm3)) 1439 1485 dnl __(ldrx(arg_x,keyword_vector,imm1)) 1440 dnl __(cmpr( cr0,arg_x,arg_z))1486 dnl __(cmpr(arg_x,arg_z)) 1441 1487 dnl __(addi imm1,imm1,fixnum_one) 1442 dnl __(bne cr0,8f)1488 dnl __(bne 8f) 1443 1489 dnl __(add imm0,imm0,imm0) 1444 1490 dnl __(sub imm0,varptr,imm0) 1445 1491 dnl __(ldr arg_x,[imm0,#0]) 1446 dnl __(cmp ri(cr0,arg_x,nil_value))1492 dnl __(cmp arg_x,#nil_value) 1447 1493 dnl __(mov arg_z,#t_value) 1448 dnl __(bne cr0,9f)1494 dnl __(bne 9f) 1449 1495 dnl __(str(arg_y,node_size(imm0))) 1450 1496 dnl __(str(arg_z,0(imm0))) … … 1466 1512 dnl /* keyword/value pairs from the vstack. */ 1467 1513 dnl __(andi. imm0,keyword_flags,(fixnum_one)|(2<<fixnumshift)) 1468 dnl __(cmpri( cr0,imm0,2<<fixnumshift))1469 dnl __(beq- cr0,badkeys)1514 dnl __(cmpri(imm0,2<<fixnumshift)) 1515 dnl __(beq- badkeys) 1470 1516 dnl __(andi. imm2,keyword_flags,4<<fixnumshift) 1471 1517 dnl __(bnelr cr0) … … 1502 1548 __(jump_fname) 1503 1549 1504 dnl /* As in the heap-consed cases, only stack-cons the &rest arg */ 1505 dnl _spentry(stack_rest_arg) 1506 dnl __(mov imm0,#0) 1507 dnl __(vpush_argregs()) 1508 dnl __(b _SPstack_cons_rest_arg) 1509 dnl 1510 dnl 1511 dnl _spentry(req_stack_rest_arg) 1512 dnl __(vpush_argregs()) 1513 dnl __(b _SPstack_cons_rest_arg) 1514 dnl 1515 dnl _spentry(stack_cons_rest_arg) 1516 dnl __(sub imm1,nargs,imm0) 1517 dnl __(cmpri(cr0,imm1,0)) 1518 dnl __(cmpri(cr1,imm1,(4096-dnode_size)/2)) 1519 dnl __(mov arg_z,#nil_value) 1520 dnl __(ble cr0,2f) /* always temp-push something. */ 1521 dnl __(bge cr1,3f) 1522 dnl __(add imm1,imm1,imm1) 1523 dnl __(dnode_align(imm2,imm1,tsp_frame.fixed_overhead)) 1524 dnl __(TSP_Alloc_Var_Boxed(imm2,imm3)) 1525 dnl __(la imm0,tsp_frame.data_offset+fulltag_cons(tsp)) 1526 dnl 1: 1527 dnl __(cmpri(cr0,imm1,cons.size)) /* last time through ? */ 1528 dnl __(subi imm1,imm1,cons.size) 1529 dnl __(vpop(arg_x)) 1530 dnl __(_rplacd(imm0,arg_z)) 1531 dnl __(_rplaca(imm0,arg_x)) 1532 dnl __(mov arg_z,imm0) 1533 dnl __(la imm0,cons.size(imm0)) 1534 dnl __(bne cr0,1b) 1535 dnl __(vpush1(arg_z)) 1536 dnl __(bx lr) 1537 dnl 2: 1538 dnl __(TSP_Alloc_Fixed_Unboxed(0)) 1539 dnl __(vpush1(arg_z)) 1540 dnl __(bx lr) 1541 dnl 3: 1542 dnl __(TSP_Alloc_Fixed_Unboxed(0)) 1543 dnl __(b _SPheap_cons_rest_arg) 1544 dnl 1550 /* As in the heap-consed cases, only stack-cons the &rest arg */ 1551 _spentry(stack_rest_arg) 1552 __(mov imm0,#0) 1553 __(vpush_argregs()) 1554 __(b _SPstack_cons_rest_arg) 1555 1556 _spentry(req_stack_rest_arg) 1557 __(vpush_argregs()) 1558 __(b _SPstack_cons_rest_arg) 1559 1560 _spentry(stack_cons_rest_arg) 1561 __(sub imm1,nargs,imm0) 1562 __(cmp imm1,#0) 1563 __(mov arg_z,#nil_value) 1564 __(ble 2f) /* always temp-push something. */ 1565 __(add imm1,imm1,imm1) 1566 __(mov temp0,imm1) 1567 __(add imm1,imm1,#node_size) 1568 __(dnode_align(imm0,imm1,node_size)) 1569 __(mov imm1,imm1,lsl #num_subtag_bits-fixnumshift) 1570 __(orr imm1,imm1,#subtag_u32_vector) 1571 __(cmp imm1,#stack_alloc_limit) 1572 __(bge 3f) 1573 __(stack_allocate_zeroed_ivector(imm1,imm0)) 1574 __(mov imm0,#subtag_simple_vector) 1575 __(strb imm0,[sp]) 1576 __(add imm0,sp,#dnode_size+fulltag_cons) 1577 1: 1578 __(subs temp0,temp0,#fixnumone) 1579 __(vpop1(arg_x)) 1580 __(_rplacd(imm0,arg_z)) 1581 __(_rplaca(imm0,arg_x)) 1582 __(mov arg_z,imm0) 1583 __(add imm0,imm0,#cons.size) 1584 __(bne 1b) 1585 __(vpush1(arg_z)) 1586 __(bx lr) 1587 2: 1588 __(movc16(imm0,make_header(1,subtag_u32_vector))) 1589 __(mov imm1,#0) 1590 __(stmdb sp!,{imm0,imm1}) 1591 __(vpush1(arg_z)) 1592 __(bx lr) 1593 3: 1594 __(movc16(imm0,make_header(1,subtag_u32_vector))) 1595 __(mov imm1,#0) 1596 __(stmdb sp!,{imm0,imm1}) 1597 __(b _SPheap_cons_rest_arg) 1598 1545 1599 1546 dnl /* Prepend all but the first two (closure code, fn) and last two */ 1547 dnl /* (function name, lfbits) elements of nfn to the "arglist". */ 1548 dnl /* Doing things this way (the same way that 68K MCL does) lets */ 1549 dnl /* functions which take "inherited arguments" work consistently */ 1550 dnl /* even in cases where no closure object is created. */ 1551 dnl _spentry(call_closure) 1552 dnl __(cmpri(cr0,nargs,nargregs<<fixnumshift)) 1553 dnl __(cmpri(cr1,nargs,fixnum_one)) 1554 dnl __(vector_length(imm0,nfn,imm0)) 1555 dnl __(subi imm0,imm0,4<<fixnumshift) /* imm0 = inherited arg count */ 1556 dnl __(mov imm1,#misc_data_offset+(2<<fixnumshift)) /* point to 1st arg */ 1557 dnl __(mov imm4,#nil_value) 1558 dnl __(ble+ cr0,local_label(no_insert)) 1559 dnl /* Some arguments have already been vpushed. Vpush imm0's worth */ 1560 dnl /* of NILs, copy those arguments that have already been vpushed from */ 1561 dnl /* the old TOS to the new, then insert all of the inerited args */ 1562 dnl /* and go to the function. */ 1563 dnl __(mov imm2,#0) 1564 dnl local_label(push_nil_loop): 1565 dnl __(addi imm2,imm2,fixnum_one) 1566 dnl __(cmpr(cr2,imm2,imm0)) 1567 dnl __(vpush1(imm4)) 1568 dnl __(bne cr2,local_label(push_nil_loop)) 1569 dnl 1570 dnl __(mov imm3,vsp) 1571 dnl __(add imm4,vsp,imm0) 1572 dnl __(subi imm2,nargs,nargregs<<fixnumshift) 1573 dnl local_label(copy_already_loop): 1574 dnl __(cmpri(cr2,imm2,fixnum_one)) 1575 dnl __(subi imm2,imm2,fixnum_one) 1576 dnl __(ldr fname,[imm4,#0]) 1577 dnl __(addi imm4,imm4,fixnum_one) 1578 dnl __(str(fname,0(imm3))) 1579 dnl __(addi imm3,imm3,fixnum_one) 1580 dnl __(bne cr2,local_label(copy_already_loop)) 1581 dnl 1582 dnl local_label(insert_loop): 1583 dnl __(cmpri(cr2,imm0,fixnum_one)) 1584 dnl __(ldrx(fname,nfn,imm1)) 1585 dnl __(addi imm1,imm1,fixnum_one) 1586 dnl __(addi nargs,nargs,fixnum_one) 1587 dnl __(subi imm0,imm0,fixnum_one) 1588 dnl __(push(fname,imm4)) 1589 dnl __(bne cr2,local_label(insert_loop)) 1590 dnl __(b local_label(go)) 1591 dnl local_label(no_insert): 1592 dnl /* nargregs or fewer args were already vpushed. */ 1593 dnl /* if exactly nargregs, vpush remaining inherited vars. */ 1594 dnl __(add imm2,imm1,imm0) 1595 dnl __(bne cr0,local_label(set_regs)) 1596 dnl local_label(vpush_remaining): 1597 dnl __(cmpri(cr2,imm0,fixnum_one)) 1598 dnl __(ldrx(fname,nfn,imm1)) 1599 dnl __(addi imm1,imm1,fixnum_one) 1600 dnl __(vpush1(fname)) 1601 dnl __(subi imm0,imm0,fixnum_one) 1602 dnl __(addi nargs,nargs,fixnum_one) 1603 dnl __(bne cr2,local_label(vpush_remaining)) 1604 dnl __(b local_label(go)) 1605 dnl local_label(set_regs): 1606 dnl /* if nargs was > 1 (and we know that it was < 3), it must have */ 1607 dnl /* been 2. Set arg_x, then vpush the remaining args. */ 1608 dnl __(ble cr1,local_label(set_y_z)) 1609 dnl local_label(set_arg_x): 1610 dnl __(subi imm0,imm0,fixnum_one) 1611 dnl __(cmpri(cr0,imm0,0)) 1612 dnl __(subi imm2,imm2,fixnum_one) 1613 dnl __(ldrx(arg_x,nfn,imm2)) 1614 dnl __(addi nargs,nargs,fixnum_one) 1615 dnl __(bne cr0,local_label(vpush_remaining)) 1616 dnl __(b local_label(go)) 1617 dnl /* Maybe set arg_y or arg_z, preceding args */ 1618 dnl local_label(set_y_z): 1619 dnl __(bne cr1,local_label(set_arg_z)) 1620 dnl /* Set arg_y, maybe arg_x, preceding args */ 1621 dnl local_label(set_arg_y): 1622 dnl __(subi imm0,imm0,fixnum_one) 1623 dnl __(cmpri(cr0,imm0,0)) 1624 dnl __(subi imm2,imm2,fixnum_one) 1625 dnl __(ldrx(arg_y,nfn,imm2)) 1626 dnl __(addi nargs,nargs,fixnum_one) 1627 dnl __(bne cr0,local_label(set_arg_x)) 1628 dnl __(b local_label(go)) 1629 dnl local_label(set_arg_z): 1630 dnl __(subi imm0,imm0,fixnum_one) 1631 dnl __(cmpri(cr0,imm0,0)) 1632 dnl __(subi imm2,imm2,fixnum_one) 1633 dnl __(ldrx(arg_z,nfn,imm2)) 1634 dnl __(addi nargs,nargs,fixnum_one) 1635 dnl __(bne cr0,local_label(set_arg_y)) 1636 dnl 1637 dnl local_label(go): 1638 dnl __(vrefr(nfn,nfn,1)) 1639 dnl __(ldr loc_pc,[nfn,#_function.codevector]) 1640 dnl __(mtctr loc_pc) 1641 dnl __(bctr) 1600 /* Prepend all but the first three (entrypoint, closure code, fn) and last two */ 1601 /* (function name, lfbits) elements of nfn to the "arglist". */ 1602 /* functions which take "inherited arguments" work consistently */ 1603 /* even in cases where no closure object is created. */ 1604 _spentry(call_closure) 1605 __(cmp nargs,nargregs<<fixnumshift) 1606 __(vector_length(imm0,nfn,imm0)) 1607 __(sub imm0,imm0,#5<<fixnumshift) /* imm0 = inherited arg count */ 1608 __(ble local_label(no_insert)) 1609 /* Some arguments have already been vpushed. Vpush imm0's worth */ 1610 /* of NILs, copy those arguments that have already been vpushed from */ 1611 /* the old TOS to the new, then insert all of the inerited args */ 1612 /* and go to the function. */ 1613 __(vpush_all_argregs()) 1614 __(mov arg_x,imm0) 1615 __(mov arg_y,#nil_value) 1616 local_label(push_nil_loop): 1617 __(subs arg_x,arg_x,#fixnumone) 1618 __(vpush1(arg_y)) 1619 __(bne local_label(push_nil_loop)) 1620 __(add arg_y,vsp,imm0) 1621 __(mov imm1,#0) 1622 local_label(copy_already_loop): 1623 __(ldr arg_x,[vsp,imm1]) 1624 __(str arg_x,[arg_y,imm1]) 1625 __(add imm1,imm1,#fixnumone) 1626 __(cmp imm1,imm0) 1627 __(bne local_label(copy_already_loop)) 1628 __(mov imm1,#misc_data_offset+(3<<fixnumshift)) 1629 __(add arg_y,vsp,nargs) 1630 __(add arg_y,arg_y,imm0) 1631 local_label(insert_loop): 1632 __(subs imm0,imm0,#fixnumone) 1633 __(ldr fname,[nfn,imm1]) 1634 __(add imm1,imm1,#fixnumone) 1635 __(add nargs,nargs,#fixnumone) 1636 __(push1(fname,arg_y)) 1637 __(bne local_label(insert_loop)) 1638 __(vpop_all_argregs()) 1639 __(b local_label(go)) 1640 local_label(no_insert): 1641 /* nargregs or fewer args were already vpushed. */ 1642 /* if exactly nargregs, vpush remaining inherited vars. */ 1643 __(cmp nargs,#nargregs<<fixnumshift) 1644 __(add imm1,imm0,#misc_data_offset+(3<<fixnumshift)) 1645 __(bne local_label(set_regs)) 1646 local_label(vpush_remaining): 1647 __(mov imm1,#misc_data_offset+(3<<fixnumshift)) 1648 local_label(vpush_remaining_loop): 1649 __(ldr fname,[nfn,imm1]) 1650 __(add imm1,imm1,#fixnum_one) 1651 __(vpush1(fname)) 1652 __(subs imm0,imm0,#fixnum_one) 1653 __(add nargs,nargs,#fixnum_one) 1654 __(bne local_label(vpush_remaining_loop)) 1655 __(b local_label(go)) 1656 local_label(set_regs): 1657 /* if nargs was > 1 (and we know that it was < 3), it must have */ 1658 /* been 2. Set arg_x, then vpush the remaining args. */ 1659 __(cmp nargs,#fixnumone) 1660 __(ble local_label(set_y_z)) 1661 local_label(set_arg_x): 1662 __(subs imm0,imm0,#fixnum_one) 1663 __(sub imm1,imm1,#fixnum_one) 1664 __(ldr arg_x,[nfn,imm1]) 1665 __(add nargs,nargs,#fixnum_one) 1666 __(bne local_label(vpush_remaining)) 1667 __(b local_label(go)) 1668 /* Maybe set arg_y or arg_z, preceding args */ 1669 local_label(set_y_z): 1670 __(cmp nargs,#fixnumone) 1671 __(bne local_label(set_arg_z)) 1672 /* Set arg_y, maybe arg_x, preceding args */ 1673 local_label(set_arg_y): 1674 __(subs imm0,imm0,fixnum_one) 1675 __(sub imm1,imm1,#fixnum_one) 1676 __(ldr arg_y,[nfn,imm1]) 1677 __(add nargs,nargs,#fixnum_one) 1678 __(bne local_label(set_arg_x)) 1679 __(b local_label(go)) 1680 local_label(set_arg_z): 1681 __(subs imm0,imm0,#fixnum_one) 1682 __(sub imm1,imm1,#fixnum_one) 1683 __(ldr arg_z,[nfn,imm1]) 1684 __(add nargs,nargs,#fixnum_one) 1685 __(bne local_label(set_arg_y)) 1686 1687 local_label(go): 1688 __(vrefr(nfn,nfn,2)) 1689 __(ldr pc,[nfn,#_function.entrypoint]) 1642 1690 1643 1691 … … 1828 1876 __(b C(misc_ref_common)) 1829 1877 1830 _spentry(builtin_aref1) 1831 __(extract_typecode(imm0,arg_y)) 1832 __(cmp imm0,#min_vector_subtag) 1833 __(box_fixnum(arg_x,imm0)) 1834 __(bgt _SPsubtag_misc_ref) 1835 __(jump_builtin(_builtin_aref1,2)) 1836 1837 dnl /* Make a "raw" area on the temp stack, stack-cons a macptr to point to it, */ 1838 dnl /* and return the macptr. Size (in bytes, boxed) is in arg_z on entry; macptr */ 1839 dnl /* in arg_z on exit. */ 1840 dnl _spentry(makestackblock) 1841 dnl __(unbox_fixnum(imm0,arg_z)) 1842 dnl __(dnode_align(imm0,imm0,tsp_frame.fixed_overhead+macptr.size)) 1843 dnl __(cmplri(cr0,imm0,tstack_alloc_limit)) 1844 dnl __(bge cr0,1f) 1845 dnl __(TSP_Alloc_Var_Unboxed(imm0)) 1846 dnl __(mov imm0,#macptr_header) 1847 dnl __(la imm1,tsp_frame.data_offset+macptr.size(tsp)) 1848 dnl __(str(imm0,tsp_frame.data_offset(tsp))) 1849 dnl __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp)) 1850 dnl __(str(imm1,macptr.address(arg_z))) 1851 dnl __(stfd fp_zero,macptr.domain(arg_z)) 1852 dnl __(bx lr) 1853 dnl 1854 dnl /* Too big. Heap cons a gcable macptr */ 1855 dnl 1: 1856 dnl __(TSP_Alloc_Fixed_Unboxed(0)) 1857 dnl __(set_nargs(1)) 1858 dnl __(mov fname,#nrs.new_gcable_ptr) 1859 dnl __(jump_fname()) 1860 dnl 1861 dnl /* As above, only set the block's contents to 0. */ 1862 dnl _spentry(makestackblock0) 1863 dnl __(unbox_fixnum(imm0,arg_z)) 1864 dnl __(dnode_align(imm0,imm0,tsp_frame.fixed_overhead+macptr.size)) 1865 dnl __(cmplri(cr0,imm0,tstack_alloc_limit)) 1866 dnl __(bge cr0,3f) 1867 dnl __(TSP_Alloc_Var_Unboxed(imm0)) 1868 dnl __(Zero_TSP_Frame(imm0,imm1)) 1869 dnl __(mov imm0,#macptr_header) 1870 dnl __(la imm1,tsp_frame.data_offset+macptr.size(tsp)) 1871 dnl __(str(imm0,tsp_frame.data_offset(tsp))) 1872 dnl __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp)) 1873 dnl __(str(imm1,macptr.address(arg_z))) /* makestackblock0 expects the address to be in imm1 */ 1874 dnl __(stfd fp_zero,macptr.domain(arg_z)) 1875 dnl __(bx lr) 1876 dnl 1877 dnl /* Too big. Heap cons a gcable macptr */ 1878 dnl 3: 1879 dnl __(TSP_Alloc_Fixed_Unboxed(0)) /* "raw" block to make the compiler happy */ 1880 dnl 1881 dnl __(mov arg_y,arg_z) /* save block size */ 1882 dnl __(mov arg_z,#t_value) /* clear-p arg to %new-gcable-ptr */ 1883 dnl __(set_nargs(2)) 1884 dnl __(mov fname,#nrs.new_gcable_ptr) 1885 dnl __(jump_fname()) 1878 1879 /* Make a "raw" area on the temp stack, stack-cons a macptr to point to it, */ 1880 /* and return the macptr. Size (in bytes, boxed) is in arg_z on entry; macptr */ 1881 /* in arg_z on exit. */ 1882 _spentry(makestackblock) 1883 __(unbox_fixnum(imm1,arg_z)) 1884 __(dnode_align(imm1,imm1,0)) 1885 __(add imm1,imm1,#macptr.size+node_size) 1886 __(add imm0,imm1,#node_size) 1887 __(mov imm1,imm1,lsl #num_subtag_bits) 1888 __(orr imm1,imm1,#subtag_u8_vector) 1889 __(cmp imm0,#stack_alloc_limit) 1890 __(bhs 1f) 1891 __(stack_allocate_ivector(imm1,imm0)) 1892 __(movc16(imm1,make_header(macptr.element_count,subtag_macptr))) 1893 __(str imm1,[sp,#dnode_size]) 1894 __(mov imm0,#0) 1895 __(str imm0,[sp,#dnode_size+macptr.type-fulltag_misc]) 1896 __(str imm0,[sp,#dnode_size+macptr.domain-fulltag_misc]) 1897 __(add imm0,sp,#macptr.size+dnode_size) 1898 __(str imm0,[sp,#dnode_size+macptr.address-fulltag_misc]) 1899 __(add arg_z,sp,#dnode_size+fulltag_misc) 1900 __(bx lr) 1901 1902 /* Too big. Heap cons a gcable macptr */ 1903 1: 1904 __(mov imm1,#subtag_u8_vector) 1905 __(str imm1,[sp,#-dnode_size]!) 1906 __(set_nargs(1)) 1907 __(ref_nrs_symbol(fname,new_gcable_ptr,imm0)) 1908 __(jump_fname()) 1909 1910 /* As above, only set the block's contents to 0. */ 1911 _spentry(makestackblock0) 1912 __(unbox_fixnum(imm1,arg_z)) 1913 __(dnode_align(imm1,imm1,0)) 1914 __(add imm1,imm1,#macptr.size+node_size) 1915 __(add imm0,imm1,#node_size) 1916 __(mov imm1,imm1,lsl #num_subtag_bits) 1917 __(orr imm1,imm1,#subtag_u8_vector) 1918 __(cmp imm0,#stack_alloc_limit) 1919 __(bhs 1f) 1920 __(stack_allocate_zeroed_ivector(imm1,imm0)) 1921 __(movc16(imm1,make_header(macptr.element_count,subtag_macptr))) 1922 __(str imm1,[sp,#dnode_size]) 1923 __(add imm0,sp,#macptr.size+dnode_size) 1924 __(str imm0,[sp,#dnode_size+macptr.address-fulltag_misc]) 1925 __(add arg_z,sp,#dnode_size+fulltag_misc) 1926 __(bx lr) 1927 /* Too big. Heap cons a gcable macptr */ 1928 1: 1929 __(mov imm1,#subtag_u8_vector) 1930 __(str imm1,[sp,#-dnode_size]!) 1931 __(mov arg_y,arg_z) /* save block size */ 1932 __(mov arg_z,#nil_value) /* clear-p arg to %new-gcable-ptr */ 1933 __(add arg_z,arg_z,#t_offset) 1934 __(set_nargs(2)) 1935 __(ref_nrs_symbol(fname,new_gcable_ptr,imm0)) 1936 __(jump_fname()) 1886 1937 1887 1938 /* Make a list of length arg_y (boxed), initial-element arg_z (boxed) on */ … … 1895 1946 __(cmp imm0,#stack_alloc_limit) 1896 1947 __(bge 4f) 1897 __(stack_allocate_zeroed_ word_vector(imm1,imm0))1948 __(stack_allocate_zeroed_ivector(imm1,imm0)) 1898 1949 __(mov imm0,#subtag_simple_vector) 1899 1950 __(strb imm0,[sp,#0]) … … 1926 1977 __(bx lr) 1927 1978 1928 dnl /* subtype (boxed) vpushed before initial values. (Had better be a */ 1929 dnl /* node header subtag.) Nargs set to count of things vpushed. */ 1930 dnl 1931 dnl _spentry(stkgvector) 1932 dnl __(la imm0,-fixnum_one(nargs)) 1933 dnl __(cmpri(cr1,imm0,0)) 1934 dnl __(add imm1,vsp,nargs) 1935 dnl __(ldru(temp0,-node_size(imm1))) 1936 dnl __(slri(imm2,imm0,num_subtag_bits-fixnumshift)) 1937 dnl __(rlwimi imm2,temp0,32-fixnumshift,32-num_subtag_bits,31) 1938 dnl __(dnode_align(imm0,imm0,node_size+tsp_frame.fixed_overhead)) 1939 dnl __(TSP_Alloc_Var_Boxed_nz(imm0,imm3)) 1940 dnl __(str(imm2,tsp_frame.data_offset(tsp))) 1941 dnl __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp)) 1942 dnl __(la imm3,misc_header_offset(arg_z)) 1943 dnl __(mov imm0,#fixnum1) 1944 dnl __(b 2f) 1945 dnl 1: 1946 dnl __(addi imm0,imm0,fixnum1) 1947 dnl __(cmpr(cr1,imm0,nargs)) 1948 dnl __(ldru(temp0,-node_size(imm1))) 1949 dnl __(stru(temp0,node_size(imm3))) 1950 dnl 2: 1951 dnl __(bne cr1,1b) 1952 dnl __(add vsp,vsp,nargs) 1953 dnl __(bx lr) 1979 /* subtype (boxed) vpushed before initial values. (Had better be a */ 1980 /* node header subtag.) Nargs set to count of things vpushed. */ 1981 1982 _spentry(stkgvector) 1983 __(sub imm0,nargs,#fixnumone) 1984 __(ldr temp0,[vsp,imm0]) 1985 __(dnode_align(temp1,imm0,node_size)) 1986 __(mov imm1,imm0,lsl #num_subtag_bits-fixnumshift) 1987 __(orr imm1,imm1,#subtag_u32_vector) 1988 __(stack_allocate_zeroed_ivector(imm1,temp1)) 1989 __(unbox_fixnum(imm1,temp0)) 1990 __(strb imm1,[sp]) 1991 __(add arg_z,sp,#fulltag_misc) 1992 __(add imm0,sp,nargs) 1993 __(b 2f) 1994 1: 1995 __(vpop1(temp0)) 1996 __(push1(temp0,imm0)) 1997 2: __(subs nargs,nargs,#fixnumone) 1998 __(bne 1b) 1999 __(add vsp,vsp,#fixnumone) 2000 __(bx lr) 1954 2001 1955 2002 /* Allocate a "fulltag_misc" object. On entry, arg_y contains the element */ … … 1994 2041 __(uuo_error_reg_not_xtype(al,arg_y,xtype_unsigned_byte_24)) 1995 2042 1996 dnl 1997 dnl 1998 dnl /* Destructuring-bind, macro-bind. */ 1999 dnl 2000 dnl /* OK to use arg_x, arg_y for whatever (tagged) purpose; */ 2001 dnl /* likewise immX regs. */ 2002 dnl /* arg_z preserved, nothing else in particular defined on exit. */ 2003 dnl /* nargs contains req count (0-255) in PPC bits mask_req_start/mask_req_width, */ 2004 dnl /* opt count (0-255) in PPC bits mask_opt_start/mask_opt_width, */ 2005 dnl /* key count (0-255) in PPC bits mask_key_start/mask_key_width, */ 2006 dnl /* opt-supplied-p flag in PPC bit mask_initopt, */ 2007 dnl /* keyp flag in PPC bit mask_keyp, */ 2008 dnl /* &allow-other-keys flag in PPC bit mask_aok, */ 2009 dnl /* &rest flag in PPC bit mask_restp. */ 2010 dnl /* When mask_keyp bit is set, keyvect contains vector of keyword symbols, */ 2011 dnl /* length key count. */ 2012 dnl 2013 dnl _spentry(macro_bind) 2014 dnl __(mov whole_reg,arg_reg) 2015 dnl __(extract_lisptag(imm0,arg_reg)) 2016 dnl __(cmpri(cr0,imm0,tag_list)) 2017 dnl __(bne- cr0,1f) 2018 dnl __(_cdr(arg_reg,arg_reg)) 2019 dnl __(b (local_label(destbind1))) 2020 dnl 1: 2021 dnl __(mov arg_y,#XCALLNOMATCH) 2022 dnl __(mov arg_z,whole_reg) 2023 dnl __(set_nargs(2)) 2024 dnl __(b _SPksignalerr) 2025 dnl 2026 dnl 2027 dnl _spentry(destructuring_bind) 2028 dnl __(Mov whole_reg,arg_reg) 2029 dnl __(b local_label(destbind1)) 2030 dnl 2031 dnl _spentry(destructuring_bind_inner) 2032 dnl __(mov whole_reg,arg_z) 2033 dnl local_label(destbind1): 2034 dnl /* Extract required arg count. */ 2035 dnl /* A bug in gas: can't handle shift count of "32" (= 0 */ 2036 dnl ifelse(eval(mask_req_width+mask_req_start),eval(32),` 2037 dnl __(clrlwi. imm0,nargs,mask_req_start) 2038 dnl ',` 2039 dnl __(extrwi. imm0,nargs,mask_req_width,mask_req_start) 2040 dnl ') 2041 dnl __(extrwi imm1,nargs,mask_opt_width,mask_opt_start) 2042 dnl __(rlwinm imm2,nargs,0,mask_initopt,mask_initopt) 2043 dnl __(rlwinm imm4,nargs,0,mask_keyp,mask_keyp) 2044 dnl __(cmpri(cr4,imm4,0)) 2045 dnl __(rlwinm imm4,nargs,0,mask_restp,mask_restp) 2046 dnl __(cmpri(cr5,imm4,0)) 2047 dnl __(cmpri(cr1,imm1,0)) 2048 dnl __(cmpri(cr2,imm2,0)) 2049 dnl /* Save entry vsp in case of error. */ 2050 dnl __(mov imm4,vsp) 2051 dnl __(beq cr0,2f) 2052 dnl 1: 2053 dnl __(cmpri(cr7,arg_reg,nil_value)) 2054 dnl __(extract_lisptag(imm3,arg_reg)) 2055 dnl __(cmpri(cr3,imm3,tag_list)) 2056 dnl __(subi imm0,imm0,1) 2057 dnl __(cmpri(cr0,imm0,0)) 2058 dnl __(beq cr7,toofew) 2059 dnl __(bne cr3,badlist) 2060 dnl __(ldr arg_x,[arg_reg,#cons.car]) 2061 dnl __(ldr arg_reg,[arg_reg,#cons.cdr]) 2062 dnl __(vpush1(arg_x)) 2063 dnl __(bne cr0,1b) 2064 dnl 2: 2065 dnl __(beq cr1,rest_keys) 2066 dnl __(bne cr2,opt_supp) 2067 dnl /* 'simple' &optionals: no supplied-p, default to nil. */ 2068 dnl simple_opt_loop: 2069 dnl __(cmpri(cr0,arg_reg,nil_value)) 2070 dnl __(extract_lisptag(imm3,arg_reg)) 2071 dnl __(cmpri(cr3,imm3,tag_list)) 2072 dnl __(subi imm1,imm1,1) 2073 dnl __(cmpri(cr1,imm1,0)) 2074 dnl __(mov imm5,#nil_value) 2075 dnl __(beq cr0,default_simple_opt) 2076 dnl __(bne cr3,badlist) 2077 dnl __(ldr arg_x,[arg_reg,#cons.car]) 2078 dnl __(ldr arg_reg,[arg_reg,#cons.cdr]) 2079 dnl __(vpush1(arg_x)) 2080 dnl __(bne cr1,simple_opt_loop) 2081 dnl __(b rest_keys) 2082 dnl default_simple_opt_loop: 2083 dnl __(subi imm1,imm1,1) 2084 dnl __(cmpri(cr1,imm1,0)) 2085 dnl default_simple_opt: 2086 dnl __(vpush1(imm5)) 2087 dnl __(bne cr1,default_simple_opt_loop) 2088 dnl __(b rest_keys) 2089 dnl /* Provide supplied-p vars for the &optionals. */ 2090 dnl opt_supp: 2091 dnl __(mov arg_y,#t_value) 2092 dnl opt_supp_loop: 2093 dnl __(cmpri(cr0,arg_reg,nil_value)) 2094 dnl __(extract_lisptag(imm3,arg_reg)) 2095 dnl __(cmpri(cr3,imm3,tag_list)) 2096 dnl __(subi imm1,imm1,1) 2097 dnl __(cmpri(cr1,imm1,0)) 2098 dnl __(beq cr0,default_hard_opt) 2099 dnl __(bne cr3,badlist) 2100 dnl __(ldr arg_x,[arg_reg,#cons.car]) 2101 dnl __(ldr arg_reg,[arg_reg,#cons.cdr]) 2102 dnl __(vpush1(arg_x)) 2103 dnl __(vpush1(arg_y)) 2104 dnl __(bne cr1,opt_supp_loop) 2105 dnl __(b rest_keys) 2106 dnl default_hard_opt_loop: 2107 dnl __(subi imm1,imm1,1) 2108 dnl __(cmpri(cr1,imm1,0)) 2109 dnl default_hard_opt: 2110 dnl __(vpush1(imm5)) 2111 dnl __(vpush1(imm5)) 2112 dnl __(bne cr1,default_hard_opt_loop) 2113 dnl rest_keys: 2114 dnl __(cmpri(cr0,arg_reg,nil_value)) 2115 dnl __(bne cr5,have_rest) 2116 dnl __(bne cr4,have_keys) 2117 dnl __(bne cr0,toomany) 2118 dnl __(bx lr) 2119 dnl have_rest: 2120 dnl __(vpush1(arg_reg)) 2121 dnl __(beqlr cr4) 2122 dnl have_keys: 2123 dnl /* Ensure that arg_reg contains a proper,even-length list. */ 2124 dnl /* Insist that its length is <= 512 (as a cheap circularity check.) */ 2125 dnl __(mov imm0,#256) 2126 dnl __(mov arg_x,arg_reg) 2127 dnl count_keys_loop: 2128 dnl __(extract_lisptag(imm3,arg_x)) 2129 dnl __(cmpri(cr3,imm3,tag_list)) 2130 dnl __(cmpri(cr0,arg_x,nil_value)) 2131 dnl __(subi imm0,imm0,1) 2132 dnl __(cmpri(cr4,imm0,0)) 2133 dnl __(beq cr0,counted_keys) 2134 dnl __(bne cr3,badlist) 2135 dnl __(ldr arg_x,[arg_x,#cons.cdr]) 2136 dnl __(extract_lisptag(imm3,arg_x)) 2137 dnl __(cmpri(cr3,imm3,tag_list)) 2138 dnl __(blt cr4,toomany) 2139 dnl __(cmpri(cr0,arg_x,nil_value)) 2140 dnl __(beq cr0,db_badkeys) 2141 dnl __(bne cr3,badlist) 2142 dnl __(ldr arg_x,[arg_x,#cons.cdr]) 2143 dnl __(b count_keys_loop) 2144 dnl counted_keys: 2145 dnl /* We've got a proper, even-length list of key/value pairs in */ 2146 dnl /* arg_reg. For each keyword var in the lambda-list, push a pair */ 2147 dnl /* of NILs on the vstack. */ 2148 dnl __(extrwi. imm0,nargs,mask_key_width,mask_key_start ) 2149 dnl __(mov imm2,imm0) /* save number of keys */ 2150 dnl __(mov imm5,#nil_value) 2151 dnl __(b push_pair_test) 2152 dnl push_pair_loop: 2153 dnl __(cmpri(cr0,imm0,1)) 2154 dnl __(subi imm0,imm0,1) 2155 dnl __(vpush1(imm5)) 2156 dnl __(vpush1(imm5)) 2157 dnl push_pair_test: 2158 dnl __(bne cr0,push_pair_loop) 2159 dnl __(slwi imm2,imm2,dnode_shift) /* pairs -> bytes */ 2160 dnl __(add imm2,vsp,imm2) /* imm2 points below pairs */ 2161 dnl __(mov imm0,#0) /* count unknown keywords so far */ 2162 dnl __(extrwi imm1,nargs,1,mask_aok) /* unknown keywords allowed */ 2163 dnl __(extrwi nargs,nargs,mask_key_width,mask_key_start) 2164 dnl /* Now, for each keyword/value pair in the list */ 2165 dnl /* a) if the keyword is found in the keyword vector, set the */ 2166 dnl /* corresponding entry on the vstack to the value and the */ 2167 dnl /* associated supplied-p var to T. */ 2168 dnl /* b) Regardless of whether or not the keyword is found, */ 2169 dnl /* if :ALLOW-OTHER-KEYS is provided with a non-nil value, */ 2170 dnl /* set the low bit of imm1 to indicate that unknown keywords */ 2171 dnl /* are acceptable. (This bit is pre-set above to the value */ 2172 dnl /* the encoded value of &allow_other_keys.) */ 2173 dnl /* c) If the keyword is not found (and isn't :ALLOW-OTHER-KEYS), increment */ 2174 dnl /* the count of unknown keywords in the high bits of imm1*/ 2175 dnl /* At the end of the list, signal an error if any unknown keywords were seen */ 2176 dnl /* but not allowed. Otherwise, return. */ 2177 dnl 2178 dnl match_keys_loop: 2179 dnl __(cmpri(cr0,arg_reg,nil_value)) 2180 dnl __(mov imm0,#0) 2181 dnl __(mov imm3,#misc_data_offset) 2182 dnl __(beq cr0,matched_keys) 2183 dnl __(ldr arg_x,[arg_reg,#cons.car]) 2184 dnl __(mov arg_y,#nrs.kallowotherkeys) 2185 dnl __(cmpr(cr3,arg_x,arg_y)) /* :ALLOW-OTHER-KEYS ? */ 2186 dnl __(ldr arg_reg,[arg_reg,#cons.cdr]) 2187 dnl __(ldr arg_y,[arg_reg,#cons.car]) 2188 dnl __(cmpr(cr4,imm0,nargs)) 2189 dnl __(ldr arg_reg,[arg_reg,#cons.cdr]) 2190 dnl __(b match_test) 2191 dnl match_loop: 2192 dnl __(ldrx(temp0,keyvect_reg,imm3)) 2193 dnl __(cmpr(cr0,arg_x,temp0)) 2194 dnl __(addi imm0,imm0,1) 2195 dnl __(cmpr(cr4,imm0,nargs)) 2196 dnl __(addi imm3,imm3,node_size) 2197 dnl __(bne cr0,match_test) 2198 dnl /* Got a hit. Unless this keyword's been seen already, set it. */ 2199 dnl __(slwi imm0,imm0,dnode_shift) 2200 dnl __(subf imm0,imm0,imm2) 2201 dnl __(ldr temp0,[imm0,#0]) 2202 dnl __(cmpri(cr0,temp0,nil_value)) 2203 dnl __(mov temp0,#t_value) 2204 dnl __(bne cr0,match_keys_loop) /* already saw this */ 2205 dnl __(str(arg_y,node_size*1(imm0))) 2206 dnl __(str(temp0,node_size*0(imm0))) 2207 dnl __(bne cr3,match_keys_loop) 2208 dnl __(b match_keys_check_aok) 2209 dnl match_test: 2210 dnl __(bne cr4,match_loop) 2211 dnl __(beq cr3,match_keys_check_aok) 2212 dnl __(addi imm1,imm1,node_size) 2213 dnl __(b match_keys_loop) 2214 dnl match_keys_check_aok: 2215 dnl __(andi. imm0,imm1,2) /* check "seen-aok" bit in imm1 */ 2216 dnl __(cmpri cr1,arg_y,nil_value) /* check value */ 2217 dnl __(ori imm1,imm1,2) 2218 dnl __(bne cr0,match_keys_loop) /* duplicate aok */ 2219 dnl __(beq cr1,match_keys_loop) 2220 dnl __(ori imm1,imm1,1) 2221 dnl __(b match_keys_loop) 2222 dnl matched_keys: 2223 dnl __(clrrwi. imm0,imm1,2) 2224 dnl __(beqlr) 2225 dnl __(andi. imm1,imm1,1) 2226 dnl __(bnelr) 2227 dnl /* Some unrecognized keywords. Complain generically about */ 2228 dnl /* invalid keywords. */ 2229 dnl db_badkeys: 2230 dnl __(mov arg_y,#XBADKEYS) 2231 dnl __(b destructure_error) 2232 dnl toomany: 2233 dnl __(mov arg_y,#XCALLTOOMANY) 2234 dnl __(b destructure_error) 2235 dnl toofew: 2236 dnl __(mov arg_y,#XCALLTOOFEW) 2237 dnl __(b destructure_error) 2238 dnl badlist: 2239 dnl __(mov arg_y,#XCALLNOMATCH) 2240 dnl /* b destructure_error */ 2241 dnl destructure_error: 2242 dnl __(mov vsp,imm4) /* undo everything done to the stack */ 2243 dnl __(mov arg_z,whole_reg) 2244 dnl __(set_nargs(2)) 2245 dnl __(b _SPksignalerr) 2246 dnl 2043 2044 2045 /* Destructuring-bind, macro-bind. */ 2046 2047 /* OK to use arg_x, arg_y for whatever (tagged) purpose; */ 2048 /* likewise immX regs. */ 2049 /* arg_z preserved, nothing else in particular defined on exit. */ 2050 /* nargs contains req count (0-255) in PPC bits mask_req_start/mask_req_width, */ 2051 /* opt count (0-255) in PPC bits mask_opt_start/mask_opt_width, */ 2052 /* key count (0-255) in PPC bits mask_key_start/mask_key_width, */ 2053 /* opt-supplied-p flag in PPC bit mask_initopt, */ 2054 /* keyp flag in PPC bit mask_keyp, */ 2055 /* &allow-other-keys flag in PPC bit mask_aok, */ 2056 /* &rest flag in PPC bit mask_restp. */ 2057 /* When mask_keyp bit is set, keyvect contains vector of keyword symbols, */ 2058 /* length key count. */ 2059 2060 _spentry(macro_bind) 2061 __(mov whole_reg,arg_reg) 2062 __(extract_lisptag(imm0,arg_reg)) 2063 __(cmp imm0,#tag_list) 2064 __(bne 1f) 2065 __(_cdr(arg_reg,arg_reg)) 2066 __(b C(destbind1)) 2067 1: 2068 __(mov arg_y,#XCALLNOMATCH) 2069 __(mov arg_z,whole_reg) 2070 __(set_nargs(2)) 2071 __(b _SPksignalerr) 2072 2073 _spentry(destructuring_bind) 2074 __(mov whole_reg,arg_reg) 2075 __(b C(destbind1)) 2076 2077 _spentry(destructuring_bind_inner) 2078 __(mov whole_reg,arg_z) 2079 __(b C(destbind1)) 2080 2247 2081 dnl /* vpush the values in the value set atop the vsp, incrementing nargs. */ 2248 2082 dnl /* Discard the tsp frame; leave values atop the vsp. */ … … 2257 2091 dnl local_label(walkloop): 2258 2092 dnl __(ldr imm3,[imm1,#tsp_frame.fixed_overhead+node_size]) /* next segment */ 2259 dnl __(cmpr( cr0,imm0,imm3)) /* last segment? */2093 dnl __(cmpr(imm0,imm3)) /* last segment? */ 2260 2094 dnl __(str(imm2,tsp_frame.fixed_overhead+node_size(imm1))) /* reverse pointer */ 2261 2095 dnl __(mov imm2,imm1) /* last segment <- current segment */ 2262 2096 dnl __(mov imm1,imm3) /* current segment <- next segment */ 2263 dnl __(bne cr0,local_label(walkloop))2097 dnl __(bne local_label(walkloop)) 2264 2098 dnl 2265 2099 dnl /* the final segment ptr is now in imm2 */ … … 2267 2101 dnl local_label(pushloop): 2268 2102 dnl __(ldr imm0,[imm2,#tsp_frame.data_offset]) /* nargs in segment */ 2269 dnl __(cmpri( cr0,imm0,0))2103 dnl __(cmpri(imm0,0)) 2270 2104 dnl __(cmpr(cr1,imm2,tsp)) 2271 2105 dnl __(la imm3,tsp_frame.data_offset+(2*node_size)(imm2)) … … 2275 2109 dnl 1: 2276 2110 dnl __(ldru(arg_z,-node_size(imm3))) 2277 dnl __(cmpri( cr0,imm0,fixnum_one))2111 dnl __(cmpri(imm0,fixnum_one)) 2278 2112 dnl __(subi imm0,imm0,fixnum_one) 2279 2113 dnl __(vpush1(arg_z)) 2280 2114 dnl 2: 2281 dnl __(bne cr0,1b)2115 dnl __(bne 1b) 2282 2116 dnl __(ldr imm2,[imm2,#tsp_frame.data_offset+node_size]) /* previous segment */ 2283 2117 dnl __(bne cr1,local_label(pushloop)) … … 2343 2177 dnl __(cmpri(cr4,imm0,2<<fixnumshift)) 2344 2178 dnl __(add imm1,arg_z,imm0) 2345 dnl __(cmpri( cr0,imm0,0))2179 dnl __(cmpri(imm0,0)) 2346 2180 dnl __(add nargs,nargs,imm0) 2347 2181 dnl __(cmpri(cr1,nargs,0)) … … 2350 2184 dnl __(bge cr3,9f) 2351 2185 dnl __(beq cr4,2f) 2352 dnl __(bne cr0,1f)2186 dnl __(bne 1f) 2353 2187 dnl /* lexpr count was 0; vpop the arg regs that */ 2354 2188 dnl /* were vpushed by the caller */ … … 2410 2244 dnl /* the difference between the current VSP and the target. */ 2411 2245 dnl _spentry(mvslide) 2412 dnl __(cmpri( cr0,nargs,0))2246 dnl __(cmpri(nargs,0)) 2413 2247 dnl __(mov imm3,nargs) 2414 2248 dnl __(add imm2,vsp,nargs) … … 2417 2251 dnl __(beq 2f) 2418 2252 dnl 1: 2419 dnl __(cmpri( cr0,imm3,1<<fixnumshift))2253 dnl __(cmpri(imm3,1<<fixnumshift)) 2420 2254 dnl __(subi imm3,imm3,1<<fixnumshift) 2421 2255 dnl __(ldru(temp0,-node_size(imm0))) 2422 2256 dnl __(stru(temp0,-node_size(imm2))) 2423 dnl __(bne cr0,1b)2257 dnl __(bne 1b) 2424 2258 dnl 2: 2425 2259 dnl __(mov vsp,imm2) … … 2457 2291 dnl __(add imm3,imm3,nargs) 2458 2292 dnl __(add imm0,vsp,nargs) 2459 dnl __(cmpr( cr0,imm0,vsp))2293 dnl __(cmpr(imm0,vsp)) 2460 2294 dnl __(b 2f) 2461 2295 dnl 1: 2462 2296 dnl __(ldru(arg_z,-node_size(imm0))) 2463 dnl __(cmpr( cr0,imm0,vsp))2297 dnl __(cmpr(imm0,vsp)) 2464 2298 dnl __(stru(arg_z,-node_size(imm3))) 2465 2299 dnl 2: 2466 dnl __(bne cr0,1b)2300 dnl __(bne 1b) 2467 2301 dnl __(add vsp,vsp,nargs) /* discard values */ 2468 2302 dnl __(bx lr) … … 2478 2312 dnl 2479 2313 dnl _spentry(add_values) 2480 dnl __(cmpri( cr0,nargs,0))2314 dnl __(cmpri(nargs,0)) 2481 2315 dnl __(ldr imm1,[tsp,#0]) 2482 dnl __(bne cr0,local_label(save_values_to_tsp))2316 dnl __(bne local_label(save_values_to_tsp)) 2483 2317 dnl __(bx lr) 2484 2318 dnl … … 2547 2381 dnl __(discard_lisp_frame()) 2548 2382 dnl __(bctr) 2549 dnl 2550 dnl _spentry(savecontextvsp) 2551 dnl __(ldr imm0,[rcontext,#tcr.cs_limit]) 2552 dnl __(build_lisp_frame(fn,loc_pc,vsp)) 2553 dnl __(mov fn,nfn) 2554 dnl __(trllt(sp,imm0)) 2555 dnl __(bx lr) 2556 dnl 2557 dnl _spentry(savecontext0) 2558 dnl __(add imm0,vsp,imm0) 2559 dnl __(build_lisp_frame(fn,loc_pc,imm0)) 2560 dnl __(ldr imm0,[rcontext,#tcr.cs_limit]) 2561 dnl __(mov fn,nfn) 2562 dnl __(trllt(sp,imm0)) 2563 dnl __(bx lr) 2564 dnl 2565 dnl 2566 dnl /* Like .SPrestorefullcontext, only the saved return address */ 2567 dnl /* winds up in loc-pc instead of getting thrashed around ... */ 2568 dnl _spentry(restorecontext) 2569 dnl __(ldr loc_pc,[sp,#lisp_frame.savelr]) 2570 dnl __(ldr vsp,[sp,#lisp_frame.savevsp]) 2571 dnl __(ldr fn,[sp,#lisp_frame.savefn]) 2572 dnl __(discard_lisp_frame()) 2573 dnl __(bx lr) 2383 dnl 2384 2574 2385 dnl 2575 2386 dnl … … 2582 2393 dnl _spentry(lexpr_entry) 2583 2394 dnl __(ref_global(imm1,ret1val_addr)) 2584 dnl __(cmpr( cr0,imm1,loc_pc))2395 dnl __(cmpr(imm1,loc_pc)) 2585 2396 dnl __(build_lisp_frame(fn,loc_pc,imm0)) 2586 dnl __(bne cr0,1f)2397 dnl __(bne 1f) 2587 2398 dnl __(ref_global(imm0,lexpr_return)) 2588 2399 dnl __(build_lisp_frame(rzero,imm0,vsp)) … … 2605 2416 2606 2417 2607 _spentry(builtin_div) 2608 __(jump_builtin(_builtin_div,2)) 2609 2610 _spentry(builtin_eql) 2611 __(cmp arg_y,arg_z) 2612 __(beq 1f) 2613 __(extract_fulltag(imm0,arg_y)) 2614 __(extract_fulltag(imm1,arg_z)) 2615 __(cmp imm0,imm1) 2616 __(bne 2f) 2617 __(cmp imm0,#fulltag_misc) 2618 __(bne 2f) 2619 __(jump_builtin(_builtin_eql,2)) 2620 1: __(mov arg_z,#nil_value) 2621 __(add arg_z,arg_z,#t_offset) 2622 __(bx lr) 2623 2: __(mov arg_z,#nil_value) 2624 __(bx lr) 2625 dnl 2626 dnl _spentry(builtin_length) 2627 dnl __(cmpri(cr1,arg_z,nil_value)) 2628 dnl __(extract_typecode(imm0,arg_z)) 2629 dnl __(cmpri(cr0,imm0,min_vector_subtag)) 2630 dnl __(beq cr1,1f) 2631 dnl __(cmpwi cr2,imm0,tag_list) 2632 dnl __(beq- cr0,2f) 2633 dnl __(blt- cr0,3f) 2634 dnl /* (simple-array * (*)) */ 2635 dnl __(vector_length(arg_z,arg_z,imm0)) 2636 dnl __(bx lr) 2637 dnl 1: __(mov arg_z,#0) 2638 dnl __(bx lr) 2639 dnl 2: 2640 dnl __(ldr arg_z,[arg_z,#vectorH.logsize]) 2641 dnl __(bx lr) 2642 dnl 3: __(bne cr2,8f) 2643 dnl __(mov temp2,#-1<<fixnum_shift) 2644 dnl __(mov temp0,arg_z) /* fast pointer */ 2645 dnl __(mov temp1,arg_z) /* slow pointer */ 2646 dnl 4: __(extract_lisptag(imm0,temp0)) 2647 dnl __(cmpri(cr7,temp0,nil_value)) 2648 dnl __(cmpri(cr1,imm0,tag_list)) 2649 dnl __(addi temp2,temp2,fixnum_one) 2650 dnl __(beq cr7,9f) 2651 dnl __(andi. imm0,temp2,1<<fixnum_shift) 2652 dnl __(bne cr1,8f) 2653 dnl __(extract_lisptag(imm1,temp1)) 2654 dnl __(_cdr(temp0,temp0)) 2655 dnl __(cmpri(cr1,imm1,tag_list)) 2656 dnl __(beq cr0,4b) 2657 dnl __(bne cr1,8f) 2658 dnl __(_cdr(temp1,temp1)) 2659 dnl __(cmpr(cr0,temp0,temp1)) 2660 dnl __(bne cr0,4b) 2661 2662 dnl 8: 2663 dnl __(jump_builtin(_builtin_length,1)) 2664 dnl 9: 2665 dnl __(mov arg_z,temp2) 2666 dnl __(bx lr) 2667 dnl 2668 dnl _spentry(builtin_seqtype) 2669 dnl __(extract_typecode(imm0,arg_z)) 2670 dnl __(cmpri(cr0,imm0,tag_list)) 2671 dnl __(cmpri(cr1,imm0,min_vector_subtag)) 2672 dnl __(beq cr0,1f) 2673 dnl __(blt- cr1,2f) 2674 dnl __(mov arg_z,#nil_value) 2675 dnl __(bx lr) 2676 dnl 1: __(mov arg_z,#t_value) 2677 dnl __(bx lr) 2678 dnl 2: 2679 dnl __(jump_builtin(_builtin_seqtype,1)) 2680 2681 /* This is 2682 _spentry(builtin_assq) 2683 __(b 2f) 2684 1: __(trap_unless_list(arg_z,imm0)) 2685 __(_car(arg_x,arg_z)) 2686 __(_cdr(arg_z,arg_z)) 2687 __(cmp arg_x,#nil_value) 2688 __(beq 2f) 2689 __(trap_unless_list(arg_x,imm0)) 2690 __(_car(temp0,arg_x)) 2691 __(cmp temp0,arg_y) 2692 __(bne 2f) 2693 __(mov arg_z,arg_x) 2694 __(bx lr) 2695 2: __(cmp arg_z,#nil_value) 2696 __(bne 1b) 2697 __(bx lr) 2698 2699 _spentry(builtin_memq) 2700 __(cmp arg_z,nil_value) 2701 __(b 2f) 2702 1: __(trap_unless_list(arg_z,imm0)) 2703 __(_car(arg_x,arg_z)) 2704 __(_cdr(temp0,arg_z)) 2705 __(cmp arg_x,arg_y) 2706 __(bxeq lr) 2707 __(cmp temp0,nil_value) 2708 __(mov arg_z,temp0) 2709 2: __(bne 1b) 2710 __(bx lr) 2418 2419 2711 2420 2712 2421 2713 _spentry(builtin_logbitp) 2714 /* Call out unless both fixnums,0 <= arg_y < logbitp_max_bit */ 2715 __(test_two_fixnums(arg_y,arg_z,imm0)) 2716 __(bne 1f) 2717 __(uuo_suspend_now(al)) 2718 __(cmp arg_y,#(nbits_in_word-fixnumshift)<<fixnumshift) 2719 __(bhs 1f) 2720 __(unbox_fixnum(imm0,arg_y)) 2721 __(mov imm1,#fixnum1) 2722 __(tst arg_z,imm1,lsl imm0) 2723 __(mov arg_z,#nil_value) 2724 __(addne arg_z,arg_z,#t_offset) 2725 __(bx lr) 2726 1: 2727 __(jump_builtin(_builtin_logbitp,2)) 2728 2729 _spentry(builtin_logior) 2730 __(orr imm0,arg_y,arg_z) 2731 __(test_fixnum(imm0)) 2732 __(moveq arg_z,imm0) 2733 __(bxeq lr) 2734 __(jump_builtin(_builtin_logior,2)) 2735 2736 _spentry(builtin_logand) 2737 __(test_two_fixnums(arg_y,arg_z,imm0)) 2738 __(andeq arg_z,arg_y,arg_z) 2739 __(bxeq lr) 2740 __(jump_builtin(_builtin_logand,2)) 2741 2742 _spentry(builtin_ash) 2743 __(test_two_fixnums(arg_y,arg_z,imm0)) 2744 __(bne 9f) 2745 __(cmp arg_z,#0) 2746 __(bgt 1f) 2747 __(moveq arg_z,arg_y) 2748 __(bxeq lr) 2749 /* Shift right */ 2750 __(unbox_fixnum(imm2,arg_z)) 2751 __(rsb imm2,imm2,#0) 2752 __(cmp imm2,#32) 2753 __(movge imm2,#31) 2754 __(mov arg_z,#-fixnumone) 2755 __(and arg_z,arg_z,arg_y,lsr imm2) 2756 __(bx lr) 2757 /* shift left */ 2758 1: __(unbox_fixnum(imm0,arg_y)) 2759 __(mov imm1,imm0,asr #31) 2760 __(unbox_fixnum(imm2,arg_z)) 2761 __(cmp imm2,#32) 2762 __(moveq imm1,imm0) 2763 __(moveq imm0,#0) 2764 __(beq _SPmakes64) 2765 __(bgt 9f) 2766 __(mov imm1,imm1,asl imm2) 2767 __(rsb imm2,imm2,#32) 2768 __(orr imm1,imm1,imm0,lsr imm2) 2769 __(unbox_fixnum(imm2,arg_z)) 2770 __(mov imm0,imm0,asl imm2) 2771 __(b _SPmake64) 2772 9: 2773 __(jump_builtin(_builtin_ash,2)) 2774 2775 _spentry(builtin_negate) 2776 __(test_fixnum(arg_z)) 2777 __(bne 1f) 2778 __(rsbs arg_z,arg_z,#0) 2779 __(bxvc lr) 2780 __(b _SPfix_overflow) 2781 1: 2782 __(jump_builtin(_builtin_negate,1)) 2783 dnl 2784 dnl _spentry(builtin_logxor) 2785 dnl __(extract_lisptag(imm0,arg_y)) 2786 dnl __(extract_lisptag(imm1,arg_z)) 2787 dnl __(ands imm0,imm0,imm1) 2788 dnl __(eoreq arg_z,arg_y,arg_z) 2789 dnl __(bxeq lr) 2790 dnl __(jump_builtin(_builtin_logxor,2)) 2791 dnl 2792 dnl 2793 dnl 2794 dnl 2795 dnl _spentry(builtin_aset1) 2796 dnl __(extract_typecode(imm0,arg_x)) 2797 dnl __(cmpri(cr0,imm0,min_vector_subtag)) 2798 dnl __(box_fixnum(temp0,imm0)) 2799 dnl __(bgt cr0,1f) 2800 dnl __(jump_builtin(_builtin_aset1,3)) 2801 dnl 1: 2802 dnl __(b _SPsubtag_misc_set) 2803 dnl 2804 dnl /* Enter the debugger */ 2805 dnl _spentry(breakpoint) 2806 dnl __(mov r3,#0) 2807 dnl __(tw 28,sp,sp) /* 28 = lt|gt|eq (assembler bug for the latter) */ 2808 dnl __(bx lr) /* if handler didn't */ 2809 dnl 2810 dnl /* */ 2811 dnl /* We're entered with an eabi_c_frame on the C stack. There's a */ 2812 dnl /* lisp_frame reserved underneath it; we'll link it in in a minute. */ 2813 dnl /* Load the outgoing GPR arguments from eabi_c_frame.param`0-7', */ 2814 dnl /* then shrink the eabi_c_frame. */ 2815 dnl /* */ 2816 dnl 2817 dnl _spentry(eabi_ff_call) 2818 dnl __(mflr loc_pc) 2819 dnl __(str(sp,eabi_c_frame.savelr(sp))) 2820 dnl __(vpush_saveregs()) /* Now we can use save0-save7 to point to stacks */ 2821 dnl __(mov save0,rcontext) /* or address globals. */ 2822 dnl __(extract_typecode(imm0,arg_z)) 2823 dnl __(cmpri(imm0,subtag_macptr)) 2824 dnl __(ldr save1,[sp,#0]) /* bottom of reserved lisp frame */ 2825 dnl __(la save2,-lisp_frame.size(save1)) /* top of lisp frame */ 2826 dnl __(zero_doublewords save2,0,lisp_frame.size) 2827 dnl __(str(save1,lisp_frame.backlink(save2))) 2828 dnl __(str(save2,c_frame.backlink(sp))) 2829 dnl __(str(fn,lisp_frame.savefn(save2))) 2830 dnl __(str(loc_pc,lisp_frame.savelr(save2))) 2831 dnl __(str(vsp,lisp_frame.savevsp(save2))) 2832 dnl __(bne 1f) 2833 dnl __(ldr arg_z,[arg_z,#macptr.address]) 2834 dnl 1: 2835 dnl __(ldr save3,[rcontext,#tcr.cs_area]) 2836 dnl __(str(save2,area.active(save3))) 2837 dnl __(str(allocptr,tcr.save_allocptr(rcontext))) 2838 dnl __(str(allocbase,tcr.save_allocbase(rcontext))) 2839 dnl __(str(tsp,tcr.save_tsp(rcontext))) 2840 dnl __(str(vsp,tcr.save_vsp(rcontext))) 2841 dnl __(mtctr arg_z) 2842 dnl __(str(rzero,tcr.ffi_exception(rcontext))) 2843 dnl __(mffs f0) 2844 dnl __(stfd f0,tcr.lisp_fpscr(rcontext)) /* remember lisp's fpscr */ 2845 dnl __(mtfsf 0xff,fp_zero) /* zero foreign fpscr */ 2846 dnl __(mov imm1,#TCR_STATE_FOREIGN) 2847 dnl __(str(imm1,tcr.valence(rcontext))) 2848 dnl __(ldr r2,[rcontext,#tcr.native_thread_info]) 2849 dnl __(ldr r13,[0,#lisp_globals.saveR13]) 2850 dnl __(ldr r3,[sp,#eabi_c_frame.param0]) 2851 dnl __(ldr r4,[sp,#eabi_c_frame.param1]) 2852 dnl __(ldr r5,[sp,#eabi_c_frame.param2]) 2853 dnl __(ldr r6,[sp,#eabi_c_frame.param3]) 2854 dnl __(ldr r7,[sp,#eabi_c_frame.param4]) 2855 dnl __(ldr r8,[sp,#eabi_c_frame.param5]) 2856 dnl __(ldr r9,[sp,#eabi_c_frame.param6]) 2857 dnl __(ldr r10,[sp,#eabi_c_frame.param7]) 2858 dnl __(la save1,eabi_c_frame.minsiz-eabi_c_frame.param0(sp)) 2859 dnl __(str(rzero,eabi_c_frame.savelr(save1))) 2860 dnl __(str(save2,eabi_c_frame.backlink(save1))) 2861 dnl __(mov sp,save1) 2862 dnl /* If we're calling a varargs C function, it'll want to */ 2863 dnl /* know whether or not we've passed any args in FP regs. */ 2864 dnl /* Better to say that we did (and force callee to save FP */ 2865 dnl /* arg regs on entry) than to say that we didn't and get */ 2866 dnl /* garbage results */ 2867 dnl __(crset 6) 2868 dnl __(bctrl) 2869 dnl /* C should have preserved save0 (= rcontext) for us. */ 2870 dnl __(ldr sp,[sp,#0]) 2871 dnl __(mov imm2,save0) 2872 dnl __(ldr vsp,[sp,#lisp_frame.savevsp]) 2873 dnl __(mov rzero,#0) 2874 dnl __(mov loc_pc,rzero) 2875 dnl __(mov arg_x,#nil_value) 2876 dnl __(mov arg_y,#nil_value) 2877 dnl __(mov arg_z,#nil_value) 2878 dnl __(mov temp0,#nil_value) 2879 dnl __(mov temp1,#nil_value) 2880 dnl __(mov temp2,#nil_value) 2881 dnl __(mov temp3,#nil_value) 2882 dnl __(mov fn,#nil_value) 2883 dnl __(mov rcontext,imm2) 2884 dnl __(mov imm2,#TCR_STATE_LISP) 2885 dnl __(ldr tsp,[rcontext,#tcr.save_tsp]) 2886 dnl __(mov save0,#0) 2887 dnl __(mov save1,#0) 2888 dnl __(mov save2,#0) 2889 dnl __(mov save3,#0) 2890 dnl __(mov save4,#0) 2891 dnl __(mov save5,#0) 2892 dnl __(mov save6,#0) 2893 dnl __(mov save7,#0) 2894 dnl __(mov allocptr,#-dnode_size) 2895 dnl __(mov allocbase,#-dnode_size) 2896 dnl __(str(imm2,tcr.valence(rcontext))) 2897 dnl __(vpop_saveregs()) 2898 dnl __(ldr allocptr,[rcontext,#tcr.save_allocptr]) 2899 dnl __(ldr allocbase,[rcontext,#tcr.save_allocbase]) 2900 dnl __(ldr loc_pc,[sp,#lisp_frame.savelr]) 2901 dnl __(mtlr loc_pc) 2902 dnl __(ldr fn,[sp,#lisp_frame.savefn]) 2903 dnl __(mffs f0) 2904 dnl __(stfd f0,8(sp)) 2905 dnl __(lwz imm3,12(sp)) /* imm3 = FPSCR after call */ 2906 dnl __(clrrwi imm2,imm3,8) 2907 dnl __(discard_lisp_frame()) 2908 dnl __(str(imm2,tcr.ffi_exception(rcontext))) 2909 dnl __(lfd f0,tcr.lisp_fpscr(rcontext)) 2910 dnl __(mtfsf 0xff,f0) 2911 dnl __(check_pending_interrupt(`cr1')) 2912 dnl __(mtxer rzero) 2913 dnl __(mtctr rzero) 2914 dnl __(bx lr) 2915 2916 2422 2423 2424 2425 /* Enter the debugger */ 2426 _spentry(breakpoint) 2427 __(mov r3,#0) 2428 __(uuo_debug_trap(al)) 2429 __(bx lr) /* if handler didn't */ 2917 2430 2918 2431 … … 3021 2534 dnl __(cmpri(cr1,arg_z,0)) 3022 2535 dnl __(ldr imm0,[rcontext,#tcr.interrupt_pending]) 3023 dnl __(cmpri( cr0,imm0,0))2536 dnl __(cmpri(imm0,0)) 3024 2537 dnl __(bne cr1,1f) 3025 dnl __(beq cr0,1f)2538 dnl __(beq 1f) 3026 2539 dnl __(str(rzero,tcr.interrupt_pending(rcontext))) 3027 2540 dnl __(mov nargs,#fixnum_one) … … 3034 2547 3035 2548 3036 dnl/* Construct a lisp integer out of the 32-bit signed value in imm0 */3037 dnl/* arg_z should be of type (SIGNED-BYTE 32); return unboxed result in imm0 */2549 /* Construct a lisp integer out of the 32-bit signed value in imm0 */ 2550 /* arg_z should be of type (SIGNED-BYTE 32); return unboxed result in imm0 */ 3038 2551 3039 2552 _spentry(gets32) … … 3096 2609 __(jump_fname()) 3097 2610 3098 dnl _spentry(unbind) 3099 dnl __(ldr imm1,[rcontext,#tcr.db_link]) 3100 dnl __(ldr imm2,[rcontext,#tcr.tlb_pointer]) 3101 dnl __(ldr imm3,[imm1,#binding.sym]) 3102 dnl __(ldr temp1,[imm1,#binding.val]) 3103 dnl __(ldr imm1,[imm1,#binding.link]) 3104 dnl __(str temp1,imm2,imm3) 3105 dnl __(str(imm1,tcr.db_link(rcontext))) 3106 dnl __(bx lr) 3107 dnl 3108 dnl _spentry(unbind_n) 3109 dnl __(ldr imm1,[rcontext,#tcr.db_link]) 3110 dnl __(ldr imm2,[rcontext,#tcr.tlb_pointer]) 3111 dnl 1: __(subi imm0,imm0,1) 3112 dnl __(ldr imm3,[imm1,#binding.sym]) 3113 dnl __(ldr temp1,[imm1,#binding.val]) 3114 dnl __(cmpri(imm0,0)) 3115 dnl __(ldr imm1,[imm1,#binding.link]) 3116 dnl __(str temp1,imm2,imm3) 3117 dnl __(bne 1b) 3118 dnl __(str(imm1,tcr.db_link(rcontext))) 3119 dnl __(bx lr) 3120 dnl 3121 dnl /* */ 3122 dnl /* Clobbers imm1,imm2,imm5,arg_x, arg_y */ 3123 dnl 3124 dnl _spentry(unbind_to) 3125 dnl __(ldr imm1,[rcontext,#tcr.db_link]) 3126 dnl __(ldr imm2,[rcontext,#tcr.tlb_pointer]) 3127 dnl 1: __(ldr imm5,[imm1,#binding.sym]) 3128 dnl __(ldr arg_y,[imm1,#binding.val]) 3129 dnl __(ldr imm1,[imm1,#binding.link]) 3130 dnl __(cmpr(imm0,imm1)) 3131 dnl __(str arg_y,imm2,imm5) 3132 dnl __(bne 1b) 3133 dnl __(str(imm1,tcr.db_link(rcontext))) 3134 dnl __(bx lr) 3135 dnl 3136 dnl 3137 dnl 3138 dnl /* */ 3139 dnl /* Restore the special bindings from the top of the tstack, */ 3140 dnl /* leaving the tstack frame allocated. */ 3141 dnl /* Note that there might be 0 saved bindings, in which case */ 3142 dnl /* do nothing. */ 3143 dnl /* Note also that this is -only- called from an unwind-protect */ 3144 dnl /* cleanup form, and that .SPnthrowXXX is keeping one or more */ 3145 dnl /* values in a frame on top of the tstack. */ 3146 dnl /* */ 3147 dnl 3148 dnl _spentry(progvrestore) 3149 dnl __(ldr imm0,[tsp,#tsp_frame.backlink]) /* ignore .SPnthrowXXX values frame */ 3150 dnl __(ldr imm0,[imm0,#tsp_frame.data_offset]) 3151 dnl __(cmpri(cr0,imm0,0)) 3152 dnl __(unbox_fixnum(imm0,imm0)) 3153 dnl __(bne+ cr0,_SPunbind_n) 3154 dnl __(bx lr) 3155 dnl 3156 /* Bind CCL::*INTERRUPT-LEVEL* to 0. If its value had been negative, check */ 2611 _spentry(unbind) 2612 __(ldr imm1,[rcontext,#tcr.db_link]) 2613 __(ldr temp0,[rcontext,#tcr.tlb_pointer]) 2614 __(ldr imm0,[imm1,#binding.sym]) 2615 __(ldr temp1,[imm1,#binding.val]) 2616 __(ldr imm1,[imm1,#binding.link]) 2617 __(str temp1,[temp0,imm0]) 2618 __(str imm1,[rcontext,#tcr.db_link]) 2619 __(bx lr) 2620 2621 /* Clobbers imm1,temp0,arg_x, arg_y */ 2622 _spentry(unbind_n) 2623 __(ldr imm1,[rcontext,#tcr.db_link]) 2624 __(ldr arg_x,[rcontext,#tcr.tlb_pointer]) 2625 1: __(ldr temp0,[imm1,#binding.sym]) 2626 __(ldr arg_y,[imm1,#binding.val]) 2627 __(ldr imm1,[imm1,#binding.link]) 2628 __(subs imm0,imm0,#1) 2629 __(str arg_y,[arg_x,temp0]) 2630 __(bne 1b) 2631 __(str imm1,[rcontext,#tcr.db_link]) 2632 __(bx lr) 2633 2634 /* */ 2635 /* Clobbers imm1,temp0,arg_x, arg_y */ 2636 2637 _spentry(unbind_to) 2638 do_unbind_to(imm1,temp1,arg_x,arg_y) 2639 __(bx lr) 2640 2641 2642 2643 /* */ 2644 /* Restore the special bindings from the top of the tstack, */ 2645 /* leaving the tstack frame allocated. */ 2646 /* Note that there might be 0 saved bindings, in which case */ 2647 /* do nothing. */ 2648 /* Note also that this is -only- called from an unwind-protect */ 2649 /* cleanup form, and that .SPnthrowXXX is keeping one or more */ 2650 /* values in a frame on top of the tstack. */ 2651 /* */ 2652 2653 _spentry(progvrestore) 2654 __(skip_stack_vector(imm0,imm1,sp)) 2655 /* There might be a lisp_frame at imm0. Not sure */ 2656 __(ldr imm0,[imm0,#node_size]) /* or maybe node_size+lisp_frame.size */ 2657 __(cmp imm0,#0) 2658 __(unbox_fixnum(imm0,imm0)) 2659 __(bne _SPunbind_n) 2660 __(bx lr) 2661 2662 /* Bind CCL::*INTERRUPT-LEVEL* to 0. If its value had been negative, check */ 3157 2663 /* for pending interrupts after doing so. */ 3158 2664 _spentry(bind_interrupt_level_0) … … 3314 2820 3315 2821 3316 dnl /* As for aref2 above, but temp = array, arg_x = i, arg_y = j, arg_z = newval */ 3317 dnl _spentry(aset2) 3318 dnl __(extract_typecode(imm2,temp0)) 3319 dnl __(trap_unless_lisptag_equal(arg_x,tag_fixnum,imm0)) 3320 dnl __(cmpri(cr2,imm2,subtag_arrayH)) 3321 dnl __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0)) 3322 dnl __(bne cr2,1f) 3323 dnl __(ldr imm1,[temp0,#arrayH.rank]) 3324 dnl __(cmpri(imm1,2<<fixnumshift)) 3325 dnl __(bne 1f) 3326 dnl /* It's a 2-dimensional array. Check bounds */ 3327 dnl __(ldr imm0,[temp0,#arrayH.dim0]) 3328 dnl __(trlge(arg_x,imm0)) 3329 dnl __(ldr imm0,[temp0,#arrayH.dim0+node_size]) 3330 dnl __(trlge(arg_y,imm0)) 3331 dnl __(unbox_fixnum(imm0,imm0)) 3332 dnl __(mullr(arg_x,arg_x,imm0)) 3333 dnl __(add arg_y,arg_y,arg_x) 3334 dnl /* arg_y is now row-major-index; get data vector and 3335 dnl add in possible offset */ 3336 dnl __(mov arg_x,temp0) 3337 dnl 0: __(ldr imm0,[arg_x,#arrayH.displacement]) 3338 dnl __(ldr arg_x,[arg_x,#arrayH.data_vector]) 3339 dnl __(extract_subtag(imm1,arg_x)) 3340 dnl __(cmpri(imm1,subtag_vectorH)) 3341 dnl __(add arg_y,arg_y,imm0) 3342 dnl __(bgt C(misc_set_common)) 3343 dnl __(b 0b) 3344 dnl 1: 3345 dnl __(uuo_interr(error_object_not_array_2d,temp0)) 3346 dnl 3347 dnl /* temp1 = array, temp0 = i, arg_x = j, arg_y = k, arg_z = new */ 3348 dnl _spentry(aset3) 3349 dnl __(extract_typecode(imm2,temp1)) 3350 dnl __(trap_unless_lisptag_equal(temp0,tag_fixnum,imm0)) 3351 dnl __(cmpri(cr2,imm2,subtag_arrayH)) 3352 dnl __(trap_unless_lisptag_equal(arg_x,tag_fixnum,imm0)) 3353 dnl __(bne cr2,1f) 3354 dnl __(ldr imm1,[temp1,#arrayH.rank]) 3355 dnl __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0)) 3356 dnl __(cmpri(imm1,3<<fixnumshift)) 3357 dnl __(bne 1f) 3358 dnl /* It's a 3-dimensional array. Check bounds */ 3359 dnl __(ldr imm2,arrayH.dim0+(node_size*2)(temp1))) 3360 dnl __(ldr imm1,[temp1,#arrayH.dim0+node_size]) 3361 dnl __(ldr imm0,[temp1,#arrayH.dim0]) 3362 dnl __(trlge(arg_y,imm2)) 3363 dnl __(unbox_fixnum(imm2,imm2)) 3364 dnl __(trlge(arg_x,imm1)) 3365 dnl __(unbox_fixnum(imm1,imm1)) 3366 dnl __(trlge(temp0,imm0)) 3367 dnl __(mullr(arg_x,arg_x,imm2)) 3368 dnl __(mullr(imm1,imm2,imm1)) 3369 dnl __(mullr(temp0,imm1,temp0)) 3370 dnl __(add arg_y,arg_y,arg_x) 3371 dnl __(add arg_y,arg_y,temp0) 3372 dnl __(mov arg_x,temp1) 3373 dnl 0: __(ldr temp0,[arg_x,#arrayH.displacement]) 3374 dnl __(ldr arg_x,[arg_x,#arrayH.data_vector]) 3375 dnl __(extract_subtag(imm1,arg_x)) 3376 dnl __(cmpri(imm1,subtag_vectorH)) 3377 dnl __(add arg_y,arg_y,temp0) 3378 dnl __(bgt C(misc_set_common)) 3379 dnl __(b 0b) 3380 dnl 1: 3381 dnl __(uuo_interr(error_object_not_array_3d,temp1)) 3382 dnl 3383 dnl 3384 dnl 3385 dnl 2822 /* As for aref2 above, but temp = array, arg_x = i, arg_y = j, arg_z = newval */ 2823 _spentry(aset2) 2824 __(extract_typecode(imm0,temp0)) 2825 __(cmp imm0,#subtag_arrayH) 2826 __(ldreq imm0,[temp0,#arrayH.rank]) 2827 __(cmpeq imm0,#2<<fixnumshift) 2828 __(uuo_error_reg_not_xtype(ne,temp0,xtype_array2d)) 2829 __(trap_unless_fixnum(arg_x)) 2830 __(trap_unless_fixnum(arg_y)) 2831 /* It's a 2-dimensional array. Check bounds */ 2832 __(ldr imm0,[temp0,#arrayH.dim0]) 2833 __(cmp arg_x,imm0) 2834 __(uuo_error_array_bounds(hs,arg_x,temp0)) 2835 __(ldr imm0,[temp0,#arrayH.dim0+node_size]) 2836 __(cmp arg_y,imm0) 2837 __(uuo_error_array_bounds(hs,arg_y,temp0)) 2838 __(unbox_fixnum(imm0,imm0)) 2839 __(mul temp1,arg_x,imm0) 2840 __(add arg_y,arg_y,temp1) 2841 /* arg_y is now row-major-index; get data vector and 2842 add in possible offset */ 2843 __(mov arg_x,temp0) 2844 0: __(ldr imm0,[arg_x,#arrayH.displacement]) 2845 __(ldr arg_x,[arg_x,#arrayH.data_vector]) 2846 __(extract_subtag(imm1,arg_x)) 2847 __(cmp imm1,#subtag_vectorH) 2848 __(add arg_y,arg_y,imm0) 2849 __(bgt C(misc_set_common)) 2850 __(b 0b) 2851 2852 2853 /* temp1 = array, temp0 = i, arg_x = j, arg_y = k, arg_z = new */ 2854 _spentry(aset3) 2855 __(extract_typecode(imm0,temp1)) 2856 __(cmp imm0,#subtag_arrayH) 2857 __(ldreq imm0,[temp1,#arrayH.rank]) 2858 __(cmpeq imm0,#3<<fixnumshift) 2859 __(uuo_error_reg_not_xtype(ne,temp1,xtype_array3d)) 2860 __(trap_unless_fixnum(temp0)) 2861 __(trap_unless_fixnum(arg_x)) 2862 __(trap_unless_fixnum(arg_y)) 2863 /* It's a 3-dimensional array. Check bounds */ 2864 __(ldr imm2,[temp1,#arrayH.dim0+(node_size*2)]) 2865 __(ldr imm1,[temp1,#arrayH.dim0+node_size]) 2866 __(ldr imm0,[temp1,#arrayH.dim0]) 2867 __(cmp arg_y,imm2) 2868 __(uuo_error_array_bounds(hs,arg_y,temp1)) 2869 __(cmp arg_x,imm1) 2870 __(uuo_error_array_bounds(hs,arg_x,temp1)) 2871 __(unbox_fixnum(imm1,imm1)) 2872 __(cmp temp0,imm0) 2873 __(uuo_error_array_bounds(hs,temp0,temp1)) 2874 __(mul arg_x,imm2,arg_x) 2875 __(mul imm1,imm2,imm1) 2876 __(mul temp0,imm1,temp0) 2877 __(add arg_y,arg_y,arg_x) 2878 __(add arg_y,arg_y,temp0) 2879 __(mov arg_x,temp1) 2880 0: __(ldr temp0,[arg_x,#arrayH.displacement]) 2881 __(ldr arg_x,[arg_x,#arrayH.data_vector]) 2882 __(extract_subtag(imm1,arg_x)) 2883 __(cmp imm1,#subtag_vectorH) 2884 __(add arg_y,arg_y,temp0) 2885 __(bgt C(misc_set_common)) 2886 __(b 0b) 2887 2888 3386 2889 _spentry(nmkunwind) 3387 2890 __(mov imm2,#-fixnumone) … … 4199 3702 __(mov imm2,arg_y,lsl #1) 4200 3703 __(add imm2,imm2,#misc_dfloat_offset) 4201 __(strd imm0,imm1,[arg_ z,imm2])3704 __(strd imm0,imm1,[arg_x,imm2]) 4202 3705 __(bx lr) 4203 3706 local_label(misc_set_invalid): … … 4207 3710 __(b _SPksignalerr) 4208 3711 3712 C(destbind1): 3713 dnl /* Extract required arg count. */ 3714 dnl /* A bug in gas: can't handle shift count of "32" (= 0 */ 3715 dnl ifelse(eval(mask_req_width+mask_req_start),eval(32),` 3716 dnl __(clrlwi. imm0,nargs,mask_req_start) 3717 dnl ',` 3718 dnl __(extrwi. imm0,nargs,mask_req_width,mask_req_start) 3719 dnl ') 3720 dnl __(extrwi imm1,nargs,mask_opt_width,mask_opt_start) 3721 dnl __(rlwinm imm2,nargs,0,mask_initopt,mask_initopt) 3722 dnl __(rlwinm imm4,nargs,0,mask_keyp,mask_keyp) 3723 dnl __(cmpri(cr4,imm4,0)) 3724 dnl __(rlwinm imm4,nargs,0,mask_restp,mask_restp) 3725 dnl __(cmpri(cr5,imm4,0)) 3726 dnl __(cmpri(cr1,imm1,0)) 3727 dnl __(cmpri(cr2,imm2,0)) 3728 dnl /* Save entry vsp in case of error. */ 3729 dnl __(mov imm4,vsp) 3730 dnl __(beq 2f) 3731 dnl 1: 3732 dnl __(cmpri(cr7,arg_reg,nil_value)) 3733 dnl __(extract_lisptag(imm3,arg_reg)) 3734 dnl __(cmpri(cr3,imm3,tag_list)) 3735 dnl __(subi imm0,imm0,1) 3736 dnl __(cmpri(imm0,0)) 3737 dnl __(beq cr7,toofew) 3738 dnl __(bne cr3,badlist) 3739 dnl __(ldr arg_x,[arg_reg,#cons.car]) 3740 dnl __(ldr arg_reg,[arg_reg,#cons.cdr]) 3741 dnl __(vpush1(arg_x)) 3742 dnl __(bne 1b) 3743 dnl 2: 3744 dnl __(beq cr1,rest_keys) 3745 dnl __(bne cr2,opt_supp) 3746 dnl /* 'simple' &optionals: no supplied-p, default to nil. */ 3747 dnl simple_opt_loop: 3748 dnl __(cmpri(arg_reg,nil_value)) 3749 dnl __(extract_lisptag(imm3,arg_reg)) 3750 dnl __(cmpri(cr3,imm3,tag_list)) 3751 dnl __(subi imm1,imm1,1) 3752 dnl __(cmpri(cr1,imm1,0)) 3753 dnl __(mov imm5,#nil_value) 3754 dnl __(beq default_simple_opt) 3755 dnl __(bne cr3,badlist) 3756 dnl __(ldr arg_x,[arg_reg,#cons.car]) 3757 dnl __(ldr arg_reg,[arg_reg,#cons.cdr]) 3758 dnl __(vpush1(arg_x)) 3759 dnl __(bne cr1,simple_opt_loop) 3760 dnl __(b rest_keys) 3761 dnl default_simple_opt_loop: 3762 dnl __(subi imm1,imm1,1) 3763 dnl __(cmpri(cr1,imm1,0)) 3764 dnl default_simple_opt: 3765 dnl __(vpush1(imm5)) 3766 dnl __(bne cr1,default_simple_opt_loop) 3767 dnl __(b rest_keys) 3768 dnl /* Provide supplied-p vars for the &optionals. */ 3769 dnl opt_supp: 3770 dnl __(mov arg_y,#t_value) 3771 dnl opt_supp_loop: 3772 dnl __(cmpri(arg_reg,nil_value)) 3773 dnl __(extract_lisptag(imm3,arg_reg)) 3774 dnl __(cmpri(cr3,imm3,tag_list)) 3775 dnl __(subi imm1,imm1,1) 3776 dnl __(cmpri(cr1,imm1,0)) 3777 dnl __(beq default_hard_opt) 3778 dnl __(bne cr3,badlist) 3779 dnl __(ldr arg_x,[arg_reg,#cons.car]) 3780 dnl __(ldr arg_reg,[arg_reg,#cons.cdr]) 3781 dnl __(vpush1(arg_x)) 3782 dnl __(vpush1(arg_y)) 3783 dnl __(bne cr1,opt_supp_loop) 3784 dnl __(b rest_keys) 3785 dnl default_hard_opt_loop: 3786 dnl __(subi imm1,imm1,1) 3787 dnl __(cmpri(cr1,imm1,0)) 3788 dnl default_hard_opt: 3789 dnl __(vpush1(imm5)) 3790 dnl __(vpush1(imm5)) 3791 dnl __(bne cr1,default_hard_opt_loop) 3792 dnl rest_keys: 3793 dnl __(cmpri(arg_reg,nil_value)) 3794 dnl __(bne cr5,have_rest) 3795 dnl __(bne cr4,have_keys) 3796 dnl __(bne toomany) 3797 dnl __(bx lr) 3798 dnl have_rest: 3799 dnl __(vpush1(arg_reg)) 3800 dnl __(beqlr cr4) 3801 dnl have_keys: 3802 dnl /* Ensure that arg_reg contains a proper,even-length list. */ 3803 dnl /* Insist that its length is <= 512 (as a cheap circularity check.) */ 3804 dnl __(mov imm0,#256) 3805 dnl __(mov arg_x,arg_reg) 3806 dnl count_keys_loop: 3807 dnl __(extract_lisptag(imm3,arg_x)) 3808 dnl __(cmpri(cr3,imm3,tag_list)) 3809 dnl __(cmpri(arg_x,nil_value)) 3810 dnl __(subi imm0,imm0,1) 3811 dnl __(cmpri(cr4,imm0,0)) 3812 dnl __(beq counted_keys) 3813 dnl __(bne cr3,badlist) 3814 dnl __(ldr arg_x,[arg_x,#cons.cdr]) 3815 dnl __(extract_lisptag(imm3,arg_x)) 3816 dnl __(cmpri(cr3,imm3,tag_list)) 3817 dnl __(blt cr4,toomany) 3818 dnl __(cmpri(arg_x,nil_value)) 3819 dnl __(beq db_badkeys) 3820 dnl __(bne cr3,badlist) 3821 dnl __(ldr arg_x,[arg_x,#cons.cdr]) 3822 dnl __(b count_keys_loop) 3823 dnl counted_keys: 3824 dnl /* We've got a proper, even-length list of key/value pairs in */ 3825 dnl /* arg_reg. For each keyword var in the lambda-list, push a pair */ 3826 dnl /* of NILs on the vstack. */ 3827 dnl __(extrwi. imm0,nargs,mask_key_width,mask_key_start ) 3828 dnl __(mov imm2,imm0) /* save number of keys */ 3829 dnl __(mov imm5,#nil_value) 3830 dnl __(b push_pair_test) 3831 dnl push_pair_loop: 3832 dnl __(cmpri(imm0,1)) 3833 dnl __(subi imm0,imm0,1) 3834 dnl __(vpush1(imm5)) 3835 dnl __(vpush1(imm5)) 3836 dnl push_pair_test: 3837 dnl __(bne push_pair_loop) 3838 dnl __(slwi imm2,imm2,dnode_shift) /* pairs -> bytes */ 3839 dnl __(add imm2,vsp,imm2) /* imm2 points below pairs */ 3840 dnl __(mov imm0,#0) /* count unknown keywords so far */ 3841 dnl __(extrwi imm1,nargs,1,mask_aok) /* unknown keywords allowed */ 3842 dnl __(extrwi nargs,nargs,mask_key_width,mask_key_start) 3843 dnl /* Now, for each keyword/value pair in the list */ 3844 dnl /* a) if the keyword is found in the keyword vector, set the */ 3845 dnl /* corresponding entry on the vstack to the value and the */ 3846 dnl /* associated supplied-p var to T. */ 3847 dnl /* b) Regardless of whether or not the keyword is found, */ 3848 dnl /* if :ALLOW-OTHER-KEYS is provided with a non-nil value, */ 3849 dnl /* set the low bit of imm1 to indicate that unknown keywords */ 3850 dnl /* are acceptable. (This bit is pre-set above to the value */ 3851 dnl /* the encoded value of &allow_other_keys.) */ 3852 dnl /* c) If the keyword is not found (and isn't :ALLOW-OTHER-KEYS), increment */ 3853 dnl /* the count of unknown keywords in the high bits of imm1*/ 3854 dnl /* At the end of the list, signal an error if any unknown keywords were seen */ 3855 dnl /* but not allowed. Otherwise, return. */ 3856 dnl 3857 dnl match_keys_loop: 3858 dnl __(cmpri(arg_reg,nil_value)) 3859 dnl __(mov imm0,#0) 3860 dnl __(mov imm3,#misc_data_offset) 3861 dnl __(beq matched_keys) 3862 dnl __(ldr arg_x,[arg_reg,#cons.car]) 3863 dnl __(mov arg_y,#nrs.kallowotherkeys) 3864 dnl __(cmpr(cr3,arg_x,arg_y)) /* :ALLOW-OTHER-KEYS ? */ 3865 dnl __(ldr arg_reg,[arg_reg,#cons.cdr]) 3866 dnl __(ldr arg_y,[arg_reg,#cons.car]) 3867 dnl __(cmpr(cr4,imm0,nargs)) 3868 dnl __(ldr arg_reg,[arg_reg,#cons.cdr]) 3869 dnl __(b match_test) 3870 dnl match_loop: 3871 dnl __(ldrx(temp0,keyvect_reg,imm3)) 3872 dnl __(cmpr(arg_x,temp0)) 3873 dnl __(addi imm0,imm0,1) 3874 dnl __(cmpr(cr4,imm0,nargs)) 3875 dnl __(addi imm3,imm3,node_size) 3876 dnl __(bne match_test) 3877 dnl /* Got a hit. Unless this keyword's been seen already, set it. */ 3878 dnl __(slwi imm0,imm0,dnode_shift) 3879 dnl __(subf imm0,imm0,imm2) 3880 dnl __(ldr temp0,[imm0,#0]) 3881 dnl __(cmpri(temp0,nil_value)) 3882 dnl __(mov temp0,#t_value) 3883 dnl __(bne match_keys_loop) /* already saw this */ 3884 dnl __(str(arg_y,node_size*1(imm0))) 3885 dnl __(str(temp0,node_size*0(imm0))) 3886 dnl __(bne cr3,match_keys_loop) 3887 dnl __(b match_keys_check_aok) 3888 dnl match_test: 3889 dnl __(bne cr4,match_loop) 3890 dnl __(beq cr3,match_keys_check_aok) 3891 dnl __(addi imm1,imm1,node_size) 3892 dnl __(b match_keys_loop) 3893 dnl match_keys_check_aok: 3894 dnl __(andi. imm0,imm1,2) /* check "seen-aok" bit in imm1 */ 3895 dnl __(cmpri cr1,arg_y,nil_value) /* check value */ 3896 dnl __(ori imm1,imm1,2) 3897 dnl __(bne match_keys_loop) /* duplicate aok */ 3898 dnl __(beq cr1,match_keys_loop) 3899 dnl __(ori imm1,imm1,1) 3900 dnl __(b match_keys_loop) 3901 dnl matched_keys: 3902 dnl __(clrrwi. imm0,imm1,2) 3903 dnl __(beqlr) 3904 dnl __(andi. imm1,imm1,1) 3905 dnl __(bnelr) 3906 dnl /* Some unrecognized keywords. Complain generically about */ 3907 dnl /* invalid keywords. */ 3908 dnl db_badkeys: 3909 dnl __(mov arg_y,#XBADKEYS) 3910 dnl __(b destructure_error) 3911 dnl toomany: 3912 dnl __(mov arg_y,#XCALLTOOMANY) 3913 dnl __(b destructure_error) 3914 dnl toofew: 3915 dnl __(mov arg_y,#XCALLTOOFEW) 3916 dnl __(b destructure_error) 3917 dnl badlist: 3918 dnl __(mov arg_y,#XCALLNOMATCH) 3919 dnl /* b destructure_error */ 3920 dnl destructure_error: 3921 dnl __(mov vsp,imm4) /* undo everything done to the stack */ 3922 dnl __(mov arg_z,whole_reg) 3923 dnl __(set_nargs(2)) 3924 dnl __(b _SPksignalerr) 3925 3926 /* imm2: (tstack-consed) target catch frame, imm0: count of intervening */ 3927 /* frames. If target isn't a multiple-value receiver, discard extra values */ 3928 /* (less hair, maybe.) */ 3929 C(_throw_found): 3930 pushdef(`__',` 3931 .word 0 3932 ') 3933 __(ldr imm1,[imm2,#catch_frame.mvflag]) 3934 __(cmpri(imm1,0)) 3935 __(cmpri(cr1,nargs,0)) 3936 __(mov fn,#0) 3937 __(add imm1,vsp,nargs) 3938 __(add imm1,[imm1,#-node_size]) 3939 __(bne local_label(_throw_all_values)) 3940 __(set_nargs(1)) 3941 __(beq cr1,local_label(_throw_default_1_val)) 3942 __(mov vsp,imm1) 3943 __(b local_label(_throw_all_values)) 3944 local_label(_throw_default_1_val): 3945 __(mov imm4,#nil_value) 3946 __(vpush1(imm4)) 3947 local_label(_throw_all_values): 3948 __(bl _SPnthrowvalues) 3949 __(ldr imm3,[rcontext,#tcr.catch_top]) 3950 __(ldr imm1,[rcontext,#tcr.db_link]) 3951 __(ldr imm0,[imm3,#catch_frame.db_link]) 3952 __(ldr imm4,[imm3,#catch_frame.mvflag]) 3953 __(cmpr(imm0,imm1)) 3954 __(cmpri(cr1,imm4,0)) 3955 __(add tsp,[imm3,#-((tsp_frame.fixed_overhead+fulltag_misc))]) 3956 __(beq local_label(_throw_dont_unbind)) 3957 __(bl _SPunbind_to) 3958 local_label(_throw_dont_unbind): 3959 __(add imm0,vsp,nargs) 3960 __(cmpri(nargs,0)) 3961 __(ldr imm1,[imm3,#catch_frame.csp]) 3962 __(ldr imm1,[imm1,#lisp_frame.savevsp]) 3963 __(bne cr1,local_label(_throw_multiple)) 3964 /* Catcher expects single value in arg_z */ 3965 __(ldr arg_z,[imm0,#-node_size]) 3966 __(b local_label(_throw_pushed_values)) 3967 local_label(_throw_multiple): 3968 __(beq local_label(_throw_pushed_values)) 3969 __(mov imm2,nargs) 3970 local_label(_throw_mvloop): 3971 __(sub imm2,imm2,fixnum_one) 3972 __(cmpri(imm2,0)) 3973 __(ldru(temp0,-node_size(imm0))) 3974 __(push(temp0,imm1)) 3975 __(bgt local_label(_throw_mvloop)) 3976 local_label(_throw_pushed_values): 3977 __(mov vsp,imm1) 3978 __(ldr imm1,[imm3,#catch_frame.xframe]) 3979 __(str(imm1,tcr.xframe(rcontext))) 3980 __(ldr sp,[imm3,#catch_frame.csp]) 3981 __(ldr fn,[sp,#lisp_frame.savefn]) 3982 __(ldr loc_pc,[sp,#lisp_frame.savelr]) 3983 __(discard_lisp_frame()) 3984 __(mtlr loc_pc) 3985 __(restore_catch_nvrs(imm3)) 3986 __(ldr imm3,[imm3,#catch_frame.link]) 3987 __(str(imm3,tcr.catch_top(rcontext))) 3988 __(unlink(tsp)) 3989 __(bx lr) 3990 popdef(`__') 3991 3992 C(nthrow1v): 3993 local_label(_nthrow1v_nextframe): 3994 __(subs temp2,temp2,#fixnum_one) 3995 __(ldr temp0,[rcontext,#tcr.catch_top]) 3996 __(ldr imm1,[rcontext,#tcr.db_link]) 3997 __(set_nargs(1)) 3998 __(blt local_label(_nthrow1v_done)) 3999 __(ldr arg_y,[temp0,#catch_frame.link]) 4000 __(ldr imm0,[temp0,#catch_frame.db_link]) 4001 __(cmp imm0,imm1) 4002 __(str arg_y,[rcontext,#tcr.catch_top]) 4003 __(ldr arg_y,[temp0,#catch_frame.xframe]) 4004 __(str arg_y,[rcontext,#tcr.xframe]) 4005 __(beq local_label(_nthrow1v_dont_unbind)) 4006 __(do_unbind_to(imm0,temp1,arg_x,arg_y)) 4007 local_label(_nthrow1v_dont_unbind): 4008 __(ldr temp1,[temp0,#catch_frame.catch_tag]) 4009 __(cmp temp1,#unbound_marker) /* unwind-protect ? */ 4010 __(beq local_label(_nthrow1v_do_unwind)) 4011 /* A catch frame. If the last one, restore context from there. */ 4012 __(cmp temp2,#0) 4013 __(ldreq vsp,[sp,#lisp_frame.savevsp]) 4014 __(add sp,sp,#catch_frame.size+lisp_frame.size) 4015 __(b local_label(_nthrow1v_nextframe)) 4016 local_label(_nthrow1v_do_unwind): 4017 pushdef(`__',` 4018 .word 0 4019 ') 4020 /* This is harder, but not as hard (not as much BLTing) as the */ 4021 /* multiple-value case. */ 4022 /* Save our caller's LR and FN in the csp frame created by the unwind- */ 4023 /* protect. (Clever, eh ?) */ 4024 4025 __(la tsp,-(tsp_frame.fixed_overhead+fulltag_misc)(temp0)) 4026 __(unlink(tsp)) 4027 __(ldr loc_pc,[sp,#lisp_frame.savelr]) 4028 __(ldr nfn,[sp,#lisp_frame.savefn]) 4029 __(mtctr loc_pc) /* cleanup code address. */ 4030 __(str(fn,lisp_frame.savefn(sp))) 4031 __(mflr loc_pc) 4032 __(mov fn,nfn) 4033 __(str(loc_pc,lisp_frame.savelr(sp))) 4034 __(TSP_Alloc_Fixed_Boxed(2*node_size)) /* tsp overhead, value, throw count */ 4035 __(str(arg_z,tsp_frame.data_offset(tsp))) 4036 __(str(temp2,tsp_frame.data_offset+node_size(tsp))) 4037 __(ldr vsp,[sp,#lisp_frame.savevsp]) 4038 __(str(rzero,tcr.unwinding(rcontext))) 4039 __(bctrl) 4040 __(mov imm1,#1) 4041 __(ldr arg_z,[tsp,#tsp_frame.data_offset]) 4042 __(str(imm1,tcr.unwinding(rcontext))) 4043 __(ldr temp2,[tsp,#tsp_frame.data_offset+node_size]) 4044 __(ldr fn,[sp,#lisp_frame.savefn]) 4045 __(ldr loc_pc,[sp,#lisp_frame.savelr]) 4046 __(discard_lisp_frame()) 4047 __(mtlr loc_pc) 4048 __(unlink(tsp)) 4049 __(b local_label(_nthrow1v_nextframe)) 4050 popdef(`__') 4051 local_label(_nthrow1v_done): 4052 __(mov imm0,#0) 4053 __(str imm0,[rcontext,#tcr.unwinding]) 4054 /* nargs has an undefined value here, so we can clobber it while */ 4055 /* polling for a deferred interrupt */ 4056 __(check_pending_interrupt(nargs)) 4057 __(bx lr) 4058 4059 4209 4060 _endfile -
branches/arm/lisp-kernel/arm-uuo.s
r13679 r13687 83 83 define(`uuo_error_not_callable',`unaryUUO($1,$2,2)') 84 84 define(`uuo_tlb_too_small',`unaryUUO($1,$2,4)') 85 define(`uuo_error_no_throw_tag',`unaryUUO($1,$2,5)') 85 86 86 87 /* Binary UUOs */
Note:
See TracChangeset
for help on using the changeset viewer.
