Changeset 13755


Ignore:
Timestamp:
Jun 1, 2010, 10:52:10 AM (9 years ago)
Author:
gb
Message:

Fix a few typos/brainos.
Define check_fpu_exception, define & implement discard_stack_object.
Drop the variant entry points to keyword_bind; write a (large) version
of keyword_bind that may mostly work.
Add udiv32 and sdiv32, shamelessly stolen from a textbook.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/arm/lisp-kernel/arm-spentry.s

    r13747 r13755  
    8888        __(bne 1f)
    8989        __(unbox_fixnum(imm2,arg_z))
    90         __(smull arg_z,imm1,imm2,arg_y)
    91         /* Now have a "64-bit fixnum" in imm1(high) and arg_z(low). If */
    92         /* imm1 is just a sign extension of arg_z, return arg_z */
    93         __(cmp imm1,arg_z,asr #(nbits_in_word-1))
    94         __(bxeq lr)
    95         /* Need to ashift the pair imm1:imm0 right fixnumshift bits */
    96         __(mov imm0,imm0,lsr #fixnumshift)
    97         __(and imm2,imm1,#fixnummask)
    98         __(orr imm0,imm0,imm2,lsl #(nbits_in_word-fixnumshift))
    99         __(unbox_fixnum(imm1,imm1))
     90        __(unbox_fixnum(imm0,arg_y))
     91        __(smull imm0,imm1,imm2,imm0)
    10092        __(b _SPmakes64)
    10193
     
    13251317        /* (vpush (< imm1 nargs))  */
    13261318        __(cmp imm1,nargs)
    1327         __(subeq imm1,imm1,#t_offset)
    1328         __(vpush1(imm1))
     1319        __(subeq arg_x,arg_x,#t_offset)
     1320        __(vpush1(arg_x))
    13291321        __(cmp imm1,imm0)
    13301322        __(bne 1b)
     
    13801372
    13811373
    1382 _spentry(simple_keywords)
    1383 dnl  __(mov imm0,#0)
    1384 dnl         __(vpush_argregs())
    1385 dnl         __(b _SPkeyword_bind)
    1386 dnl                 
    1387 _spentry(keyword_args)
    1388 dnl  __(vpush_argregs())
    1389 dnl         __(b _SPkeyword_bind)
    1390 dnl
    1391 dnl /* Treat the last (- nargs imm0) values on the vstack as keyword/value  */
    1392 dnl /* pairs.  There'll be imm3 keyword arguments.  Imm2 contains flags  */
    1393 dnl /* that indicate whether &allow-other-keys was specified and whether  */
    1394 dnl /* or not to leave the keyword/value pairs on the vstack for an &rest  */
    1395 dnl /* argument.  Temp3 contains a vector of keyword specifiers which we  */
    1396 dnl /* must (in general) match.  */
    1397 dnl /* If the number of arguments is greater than imm0, the difference must  */
    1398 dnl /* be even.  */
    1399 dnl /* Note that the caller hasn't yet saved its caller's context and that  */
    1400 dnl /* the temp registers used to pass next_method_context  */
    1401 dnl /* (temp1) may still have "live" values in them, as does nfn (temp2).  */
    1402 dnl
    1403 dnl define(`keyword_flags',`imm2')
    1404 dnl define(`keyword_vector',`temp3')
    1405 dnl define(`keyword_count',`imm3')
    1406 dnl
    1407 dnl
    1408 dnl
    1409 dnl define(`varptr',`save0')
    1410 dnl define(`valptr',`save1')
    1411 dnl define(`limit',`save2')
    1412 dnl
    1413 _spentry(keyword_bind)
    1414 dnl         /* Before we can really do anything, we have to  */
    1415 dnl         /* save the caller's context.  To do so, we need to know  */
    1416 dnl         /* how many args have actually been pushed.  Ordinarily, that'd  */
    1417 dnl         /* be "nargs", but we may have pushed more args than we received  */
    1418 dnl  /* if we had to default any &optionals.  */
    1419 dnl  /* So, the number of args pushed so far is the larger of nargs  */
    1420 dnl  /* and the (canonical) total of required/&optional args received.  */
    1421 dnl  __(cmpr(nargs,imm0))
    1422 dnl  __(add arg_z,vsp,nargs)
    1423 dnl  __(bge+ 1f)
    1424 dnl  __(add arg_z,vsp,imm0)
    1425 dnl 1:
    1426 dnl  __(build_lisp_frame(fn,loc_pc,arg_z))
    1427 dnl  __(mov fn,nfn)
    1428 dnl  /* If there are key/value pairs to consider, we slide them down  */
    1429 dnl  /* the vstack to make room for the value/supplied-p pairs.  */
    1430 dnl  /* The first step in that operation involves pushing imm3 pairs  */
    1431 dnl  /* of NILs.  */
    1432 dnl  /* If there aren't any such pairs, the first step is the last  */
    1433 dnl  /* step.  */
    1434 dnl  __(cmp imm3,#0)
    1435 dnl  __(mov arg_z,#0)
    1436 dnl  __(sub imm1,nargs,imm0)
    1437 dnl  __(mov imm4,vsp) /* in case odd keywords error  */
    1438 dnl  __(cmpri(cr1,imm1,0))
    1439 dnl  __(b 3f)
    1440 dnl 2:
    1441 dnl  __(addi arg_z,arg_z,fixnum_one)
    1442 dnl  __(cmplr(arg_z,imm3))
    1443 dnl  __(mov imm5,#nil_value)
    1444 dnl  __(vpush1(imm5))
    1445 dnl  __(vpush1(imm5))
    1446 dnl 3:
    1447 dnl  __(bne 2b)
    1448 dnl  __(andi. arg_z,imm1,fixnum_one)
    1449 dnl  __(blelr cr1) /* no keyword/value pairs to consider.  */
    1450 dnl  __(bne odd_keywords)
    1451 dnl  /* We have key/value pairs.  Move them to the top of the vstack,  */
    1452 dnl  /* then set the value/supplied-p vars to NIL.  */
    1453 dnl  /* Have to use some save regs to do this.  */
    1454 dnl  __(vpush1(limit))
    1455 dnl  __(vpush1(valptr))
    1456 dnl  __(vpush1(varptr))
    1457 dnl  /* recompute ptr to user args in case stack overflowed  */
    1458 dnl  __(add imm4,vsp,imm3)
    1459 dnl  __(add imm4,imm4,imm3)
    1460 dnl  __(addi imm4,imm4,3*node_size)
    1461 dnl  /* error if odd number of keyword/value args  */
    1462 dnl  __(mov varptr,imm4)
    1463 dnl  __(la limit,3*node_size(vsp))
    1464 dnl  __(mov valptr,limit)
    1465 dnl  __(mov arg_z,imm1)
    1466 dnl 4:
    1467 dnl  __(mov imm4,#nil_value)
    1468 dnl  __(subi arg_z,arg_z,2<<fixnumshift)
    1469 dnl  __(cmplri(arg_z,0))
    1470 dnl  __(ldr arg_x,[varptr,#node_size*0])
    1471 dnl  __(ldr arg_y,[varptr,#node_size*1])
    1472 dnl  __(str(imm4,node_size*0(varptr)))
    1473 dnl  __(str(imm4,node_size*1(varptr)))
    1474 dnl  __(la varptr,node_size*2(varptr))
    1475 dnl  __(str(arg_x,node_size*0(valptr)))
    1476 dnl  __(str(arg_y,node_size*1(valptr)))
    1477 dnl  __(la valptr,node_size*2(valptr))
    1478 dnl  __(bne 4b)
    1479 dnl
    1480 dnl
    1481 dnl         /* Now, iterate through each supplied keyword/value pair.  If  */
    1482 dnl         /* it's :allow-other-keys and the corresponding value is non-nil,  */
    1483 dnl         /* note that other keys will be allowed.  */
    1484 dnl         /* Find its position in the function's keywords vector.  If that's  */
    1485 dnl         /* nil, note that an unknown keyword was encountered.  */
    1486 dnl         /* Otherwise, if the keyword arg hasn't already had a value supplied,  */
    1487 dnl         /* supply it.  */
    1488 dnl         /* When done, complain if any unknown keywords were found and that  */
    1489 dnl         /* situation was unexpected.  */
    1490 dnl  __(mov imm4,valptr)
    1491 dnl 5:
    1492 dnl         __(cmpri(keyword_flags,16<<fixnumshift)) /* seen :a-o-k yet ?  */
    1493 dnl  __(ldru(arg_z,-node_size(valptr)))
    1494 dnl  __(ldru(arg_y,-node_size(valptr)))
    1495 dnl  __(cmpri(cr1,arg_y,nil_value))
    1496 dnl  __(mov arg_x,#nrs.kallowotherkeys)
    1497 dnl         /* cr6_eq <- (eq current-keyword :allow-other-keys)  */
    1498 dnl  __(cmpr(cr6,arg_x,arg_z))
    1499 dnl  __(cmpr(cr7,valptr,limit))
    1500 dnl  __(bne cr6,6f)
    1501 dnl         __(bge 6f) /* Already seen :allow-other-keys  */
    1502 dnl         __(ori keyword_flags,keyword_flags,16<<fixnumshift)
    1503 dnl  __(beq cr1,6f)
    1504 dnl  __(ori keyword_flags,keyword_flags,fixnum_one)
    1505 dnl 6:
    1506 dnl  __(cmpri(cr1,imm3,0))
    1507 dnl  __(mov imm1,#misc_data_offset)
    1508 dnl  __(mov imm0,#0)
    1509 dnl  __(b 8f)
    1510 dnl 7:
    1511 dnl  __(addi imm0,imm0,fixnum_one)
    1512 dnl  __(cmpr(cr1,imm0,imm3))
    1513 dnl  __(ldrx(arg_x,keyword_vector,imm1))
    1514 dnl  __(cmpr(arg_x,arg_z))
    1515 dnl  __(addi imm1,imm1,fixnum_one)
    1516 dnl  __(bne 8f)
    1517 dnl  __(add imm0,imm0,imm0)
    1518 dnl  __(sub imm0,varptr,imm0)
    1519 dnl  __(ldr arg_x,[imm0,#0])
    1520 dnl  __(cmp arg_x,#nil_value)
    1521 dnl  __(mov arg_z,#t_value)
    1522 dnl  __(bne 9f)
    1523 dnl  __(str(arg_y,node_size(imm0)))
    1524 dnl  __(str(arg_z,0(imm0)))
    1525 dnl  __(b 9f)
    1526 dnl 8:
    1527 dnl  __(bne cr1,7b)
    1528 dnl  /* Unknown keyword. If it was :allow-other-keys, cr6_eq will still */
    1529 dnl         /* be set.  */
    1530 dnl         __(beq cr6,9f)
    1531 dnl  __(ori keyword_flags,keyword_flags,2<<fixnumshift)
    1532 dnl 9:
    1533 dnl  __(bne cr7,5b)
    1534 dnl  __(vpop(varptr))
    1535 dnl  __(vpop(valptr))
    1536 dnl  __(vpop(limit))
    1537 dnl  /* All keyword/value pairs have been processed.  */
    1538 dnl  /* If we saw an unknown keyword and didn't expect to, error.  */
    1539 dnl  /* Unless bit 2 is set in the fixnum in keyword_flags, discard the  */
    1540 dnl  /* keyword/value pairs from the vstack.  */
    1541 dnl  __(andi. imm0,keyword_flags,(fixnum_one)|(2<<fixnumshift))
    1542 dnl  __(cmpri(imm0,2<<fixnumshift))
    1543 dnl  __(beq- badkeys)
    1544 dnl  __(andi. imm2,keyword_flags,4<<fixnumshift)
    1545 dnl  __(bnelr cr0)
    1546 dnl  __(mov vsp,imm4)
    1547 dnl  __(bx lr)
    1548 dnl
    1549 dnl /* Signal an error.  We saved context on entry, so this thing doesn't  */
    1550 dnl /* have to.  */
    1551 dnl /* The "unknown keywords" error could be continuable (ignore them.)  */
    1552 dnl /* It might be hard to then cons an &rest arg.  */
    1553 dnl /* In the general case, it's hard to recover the set of args that were  */
    1554 dnl /* actually supplied to us ...  */
    1555 dnl /* For now, just cons a list out of the keyword/value pairs */
    1556 dnl /* that were actually provided, and signal an "invalid keywords" */
    1557 dnl /* error with that list as an operand.  */
    1558 dnl odd_keywords:
    1559 dnl  __(mov vsp,imm4)
    1560 dnl  __(mov nargs,imm1)
    1561 dnl  __(b 1f)
    1562 dnl badkeys:
    1563 dnl  __(sub nargs,imm4,vsp)
    1564 dnl 1:
    1565 dnl  __(bl _SPconslist)
    1566 dnl  __(mov arg_y,#XBADKEYS)
    1567 dnl  __(set_nargs(2))
    1568 dnl  __(b _SPksignalerr)
    1569 dnl
     1374_spentry(check_fpu_exception)
     1375
     1376_spentry(discard_stack_object)
     1377        new_local_labels()       
     1378        __(ldr imm0,[sp,#0])
     1379        __(cmp imm0,#stack_alloc_marker)
     1380        __(ldreq sp,[sp,#node_size])
     1381        __(bxeq lr)
     1382        __(cmp imm0,#lisp_frame_marker)
     1383        __(extract_fulltag(imm1,imm0))
     1384        __(addeq sp,sp,#lisp_frame.size)
     1385        __(bxeq lr)
     1386        __(cmp imm1,#fulltag_immheader)
     1387        __(and imm1,imm0,#subtag_mask)
     1388        __(bic imm0,imm0,#subtag_mask)
     1389        __(beq local_label(ivector))
     1390local_label(word):
     1391        __(mov imm0,imm0,lsr #num_subtag_bits-word_shift)
     1392local_label(out):       
     1393        __(dnode_align(imm0,imm0,node_size))
     1394        __(add sp,sp,imm0)
     1395        __(bx lr)
     1396local_label(ivector):     
     1397        __(cmp imm1,#max_32_bit_ivector_subtag)
     1398        __(bls local_label(word))       
     1399        __(cmp imm1,#max_8_bit_ivector_subtag)
     1400        __(movls imm0,imm0,lsr #num_subtag_bits)
     1401        __(bls local_label(out))
     1402        __(cmp imm1,#max_16_bit_ivector_subtag)
     1403        __(movls imm0,imm0,lsr #num_subtag_bits-1)
     1404        __(bls local_label(out))
     1405        __(cmp imm1,#subtag_bit_vector)
     1406        __(moveq imm0,imm0,lsr #num_subtag_bits)
     1407        __(addeq imm0,imm0,#7)
     1408        __(moveq imm0,imm0,lsr #3)
     1409        __(beq local_label(out))
     1410        /* The infamous 'stack-consed double-float vector' case */
     1411        __(mov imm0,imm0,lsr #num_subtag_bits-dnode_shift)
     1412        __(b local_label(out))
     1413
     1414
     1415       
    15701416/* Signal an error synchronously, via %ERR-DISP.  */
    15711417/* If %ERR-DISP isn't fbound, it'd be nice to print a message  */
     
    28562702
    28572703
     2704/* Treat the last (- nargs imm0) values on the vstack as keyword/value  */
     2705/* pairs.  There'll be arg_z keyword arguments.  arg_y contains flags  */
     2706/* that indicate whether &allow-other-keys was specified and whether  */
     2707/* or not to leave the keyword/value pairs on the vstack for an &rest  */
     2708/* argument.  Element 2 of the function in fn contains a vector of keyword.  */
     2709/* If the number of arguments is greater than imm0, the difference must  */
     2710/* be even.  */
     2711/* All arg regs have been vpushed and the calling function has built a */
     2712/* stack frame.  next_method_context must be preserved, as must the incoming */
     2713/* key/value pairs and their number if we're going to make an &rest arg. */
     2714           
     2715
     2716define(`keyword_flags',`arg_y')
     2717define(`key_value_count',`arg_z')
     2718
     2719define(`keyword_flag_allow_other_keys',`(1<<fixnumshift)')
     2720define(`keyword_flag_seen_allow_other_keys',`(2<<fixnumshift)')
     2721define(`keyword_flag_unknown_keyword_seen',`(3<<fixnumshift)')
     2722define(`keyword_flag_rest',`(4<<fixnumshift)')
     2723
     2724_spentry(keyword_bind)
     2725        new_local_labels()       
     2726        __(subs key_value_count,nargs,imm0)
     2727        __(movmi key_value_count,#0)
     2728        __(tst key_value_count,#fixnumone)
     2729        __(bne local_label(odd_keywords))
     2730        __(mov imm1,key_value_count,lsl #num_subtag_bits-fixnumshift)
     2731        __(orr imm1,imm1,subtag_u32_vector)
     2732        __(add imm0,key_value_count,#dnode_size) /* we know  count is even */
     2733        __(stack_allocate_zeroed_ivector(imm1,imm0))
     2734        __(mov imm0,#subtag_simple_vector)
     2735        __(strb imm0,[sp])
     2736        /* Copy key/value pairs in reverse order from the vstack to
     2737           the gvector we just created on the cstack. */
     2738        __(add imm0,vsp,key_value_count) /* src, predecrement */
     2739        __(add imm1,sp,#node_size)       /* dest, postincrement */
     2740        __(mov temp2,key_value_count)
     2741        __(b 1f)
     27420:      __(ldr arg_x,[imm0,#-node_size]!)
     2743        __(str arg_x,[imm1],#node_size)
     27441:      __(subs temp2,temp2,#fixnumone)
     2745        __(bge 0b)
     2746        /* Discard the key/value pairs from the vstack. */
     2747        __(add vsp,vsp,key_value_count)
     2748        __(ldr temp2,[fn,#misc_data_offset+(2*node_size)])
     2749        __(getvheader(imm0,temp2))
     2750        __(mov imm0,imm0,lsr #num_subtag_bits)
     2751        __(mov temp0,vsp)
     2752        __(mov imm1,#nil_value)
     2753        /* Push a pair of NILs (value, supplied-p) for each defined keyword */
     2754        __(b 3f)
     27552:      __(vpush1(imm1))
     2756        __(vpush1(imm1))
     27573:      __(subs imm0,imm0,#1)
     2758        __(bge 2f)
     2759        /* Save nargs and temp1 so that we can use them in the loop(s) */
     2760        __(stmdb vsp!,{imm2,temp1})
     2761        /* For each provided key/value pair: if the key is :allow-other-keys
     2762           and that hasn't been seen before, note that it's been seen and
     2763           if the value is non-nil set the allow-other-keys bit in flags.
     2764           Then search for the key in the defined keys vector.  If it's
     2765           not found, note that an undefined keyword was seen by setting
     2766           a bit in keyword_flags ; if it is found, use its position to
     2767           index the table of value/supplied-p pairs that we pushed above.
     2768           If the supplied-p var is already set, do nothing; otherwise,
     2769           set the supplied-p var and value.
     2770           When done, signal an error if we got an unknown keyword, or
     2771           either copy the supplied key/value pairs back to the vstack
     2772           if we're going to cons an &rest arg or discard them if we aren't.
     2773        */
     2774        __(mov imm2,#0)
     2775        __(b local_label(nextvalpairtest))
     2776local_label(nextvalpairloop):   
     2777        __(add temp1,sp,#4)
     2778        __(ldr temp1,[temp1,imm2])
     2779        __(ref_nrs_symbol(imm1,kallowotherkeys,imm1))
     2780        __(cmp temp1,imm1)
     2781        __(tsteq keyword_flags,#keyword_flag_seen_allow_other_keys)
     2782        __(bne local_label(current_key_allow_other_keys_handled))
     2783        __(orr keyword_flags,keyword_flags,#keyword_flag_seen_allow_other_keys)
     2784        /* Fortunately, we know what the keyword is.  Need to check the
     2785           value here, and don't have a lot of free registers ... */
     2786        __(add temp1,sp,#8)
     2787        __(ldr temp1,[temp1,imm2])
     2788        __(cmp temp1,#nil_value)
     2789        __(orrne keyword_flags,keyword_flags,#keyword_flag_allow_other_keys)
     2790        __(mov temp1,imm1)      /* from comparison above */
     2791local_label(current_key_allow_other_keys_handled):
     2792        __(getvheader(imm0,temp1))
     2793        __(header_length(imm0,imm0))
     2794        __(add imm0,imm0,#misc_data_offset)
     2795        __(b local_label(defined_keyword_compare_test))
     2796local_label(defined_keyword_compare_loop):     
     2797        __(ldr arg_x,[temp2,imm0])
     2798        __(cmp arg_x,temp1)
     2799        __(subeq imm0,imm0,#misc_data_offset)
     2800        __(beq local_label(defined_keyword_found))
     2801local_label(defined_keyword_compare_test):     
     2802        __(sub imm0,imm0,#node_size)
     2803        __(cmp imm0,#misc_data_offset)
     2804        __(bge local_label(defined_keyword_compare_loop))
     2805        /* keyword wasn't defined.  Note that ... */
     2806        __(orr keyword_flags,keyword_flags,#keyword_flag_unknown_keyword_seen)
     2807        __(b local_label(nextkeyvalpairnext))
     2808local_label(defined_keyword_found):     
     2809        __(sub imm0,temp0,imm0,lsl #1)
     2810        __(ldr arg_x,[imm0,#-4])
     2811        __(cmp arg_x,#nil_value) /* seen this keyword yet ? */
     2812        __(bne local_label(nextkeyvalpairnext))
     2813        __(add arg_x,arg_x,#t_offset)
     2814        __(str arg_x,[imm0,#-4])
     2815        __(add temp1,sp,#8)
     2816        __(ldr temp1,[temp1,imm2])
     2817        __(str temp1,[imm0,#0])
     2818local_label(nextkeyvalpairnext):
     2819        __(add imm2,imm2,#8)
     2820local_label(nextvalpairtest):   
     2821        __(cmp imm2,key_value_count)
     2822        __(bne local_label(nextvalpairloop))
     2823        __(ldmia vsp!,{imm2,temp1})
     2824        /* If unknown keywords and that's not allowed, signal error.
     2825           Otherwise, discard the stack-consed vector and return,
     2826           possibly after having copied the vector's contents back
     2827           to the vstack so that an &rest arg can be constructed.
     2828        */
     2829        __(tst keyword_flags,#keyword_flag_unknown_keyword_seen)
     2830        __(beq 0f)
     2831        __(tst keyword_flags,#keyword_flag_allow_other_keys)
     2832        __(beq local_label(badkeys))
     28330:      __(tst keyword_flags,#keyword_flag_rest)
     2834        __(beq local_label(discard_stack_vector))
     2835        __(mov nargs,#0)
     2836        __(add temp2,sp,#node_size)
     2837        __(b 2f)
     28381:      __(ldr arg_x,[temp2],#node_size)
     2839        __(vpush1(arg_x))
     2840        __(add nargs,nargs,#fixnumone)
     28412:      __(cmp nargs,key_value_count)
     2842        __(bne 1b)
     2843local_label(discard_stack_vector):     
     2844        __(add key_value_count,key_value_count,#dnode_size)
     2845        __(add sp,sp,key_value_count)
     2846        __(bx lr)               /* it's finally over ! */
     2847
     2848local_label(badkeys):   /* Disturbingly similar to the &rest case */
     2849        __(mov nargs,#0)
     2850        __(add temp2,sp,#node_size)
     2851        __(mov vsp,temp0)
     2852        __(b 1f)
     28530:      __(ldr arg_x,[temp2],#node_size)
     2854        __(vpush1(arg_x))
     2855        __(add nargs,nargs,#fixnumone)
     28561:      __(cmp nargs,key_value_count)
     2857        __(bne 0b)
     2858        /* Lose the stack vector */
     2859        __(add key_value_count,key_value_count,#dnode_size)
     2860        __(add sp,sp,key_value_count)
     2861local_label(error_exit):               
     2862        __(bl _SPconslist)
     2863        __(mov arg_y,#XBADKEYS)
     2864        __(set_nargs(2))
     2865        __(b _SPksignalerr)
     2866local_label(odd_keywords):       
     2867        __(mov nargs,key_value_count)
     2868        __(b local_label(error_exit))
     2869
     2870/* Most ARMs don't have hardware integer division.  This algorithm's
     2871  from Sloss, Symes, & Wright.  On entry: imm0 = numerator, imm1 = denominator;
     2872  on exit, imm0 = quotient, imm1 = remainder, imm2 clobbered.  Check for /0
     2873  here, so that callers don't have to.
     2874*/       
     2875_spentry(udiv32)
     2876        __(cmp imm0,#0)
     2877        __(moveq arg_z,#XDIVZRO)
     2878        __(moveq nargs,#1<<fixnumshift)
     2879        __(beq _SPksignalerr)
     2880        __(ldr imm2,[rcontext,#tcr.flags])
     2881        __(orr imm2,imm2,#(1<<TCR_FLAG_BIT_ALLOCPTR_FOREIGN))
     2882        __(str imm2,[rcontext,#tcr.flags])
     2883        __(vpush1(rcontext))
     2884        /* Hopefully safe now to use r3 (rcontext) and r12 (allocptr)
     2885           as imm regs. */
     2886pushdef(`q',`r0')
     2887pushdef(`r',`r1')
     2888pushdef(`s',`r2')
     2889pushdef(`m',`r3')
     2890pushdef(`a',`r12')
     2891        __(clz s,q)
     2892        __(movs a,q,lsl s)
     2893        __(add a,pc,a,lsr #25)
     2894        __(ldrbeq a,[a,#local_label(t32)-local_label(b32)-64])
     2895local_label(b32):
     2896        __(subs s,s,#7)
     2897        __(rsb m,q,#0)
     2898        __(movpl q,a,lsl s)
     2899        __(mulpl a,q,m)
     2900        __(bmi local_label(udiv_by_large_d))
     2901        __(smlawt q,q,a,q)
     2902        __(teq m,m,asr #1)
     2903        __(mulne a,q,m)
     2904        __(movne s,#0)
     2905        __(smlalne s,q,a,q)
     2906        __(beq local_label(udiv_by_1))
     2907        __(umull s,q,r,q)
     2908        __(add r,r,m)
     2909        __(mla r,q,m,r)
     2910        __(cmn r,m)
     2911        __(subcs r,r,m)
     2912        __(addcc q,q,#1)
     2913        __(addpl r,r,m,lsl #1)
     2914        __(addpl q,q,#2)
     2915        __(b local_label(done))
     2916local_label(udiv_by_large_d):       
     2917        __(sub a,a,#4)
     2918        __(rsb s,s,#0)
     2919        __(mov q,a,lsr s)
     2920        __(umull s,q,r,q)
     2921        __(mla r,q,m,r)
     2922        __(cmn m,r,lsr #1)
     2923        __(addcs r,r,m,lsl #1)
     2924        __(addcs q,q,#2)
     2925        __(cmn m,r)
     2926        __(addcs q,q,#1)
     2927        __(b local_label(done))
     2928local_label(udiv_by_1):
     2929        __(mov q,r)
     2930        __(mov r,#0)
     2931local_label(done):   
     2932        __(mov allocptr,#-8)
     2933        __(vpop1(rcontext))
     2934        __(ldr imm2,[rcontext,tcr.flags])
     2935        __(bic imm2,imm2,#(1<<TCR_FLAG_BIT_ALLOCPTR_FOREIGN))
     2936        __(str imm2,[rcontext,tcr.flags])
     2937        __(ldr allocptr,[rcontext,tcr.save_allocptr])
     2938        __(bx lr)
     2939popdef(`s')
     2940popdef(`m')
     2941popdef(`a')
     2942popdef(`q')
     2943popdef(`r')
     2944local_label(t32):   
     2945        .byte 0xff,0xfc,0xf8,0xf4,0xf0,0xed,0xea,0xe6
     2946        .byte 0xe3,0xe0,0xdd,0xda,0xd7,0xd4,0xd2,0xcf
     2947        .byte 0xcc,0xca,0xc7,0xc5,0xc3,0xc0,0xbe,0xbc
     2948        .byte 0xba,0xb8,0xb6,0xb4,0xb2,0xb0,0xae,0xac
     2949        .byte 0xaa,0xa8,0xa7,0xa5,0xa3,0xa2,0xa0,0x9f
     2950        .byte 0x9d,0x9c,0x9a,0x99,0x97,0x96,0x94,0x93
     2951        .byte 0x92,0x90,0x8f,0x8e,0x8d,0x8c,0x8a,0x89
     2952        .byte 0x88,0x87,0x86,0x85,0x84,0x83,0x82,0x81
     2953
     2954_spentry(sdiv32)
     2955        __(build_lisp_frame(imm2))
     2956pushdef(`sign',`temp0')
     2957pushdef(`d',`r0')
     2958pushdef(`r',`r1')               
     2959        __(ands sign,d,#0x80000000)
     2960        __(rsbmi d,d,#0)
     2961        __(eors sign,sign,r,asr #32)
     2962        __(rsbcs r,r,#0)
     2963        __(bl _SPudiv32)
     2964        __(movs sign,sign,lsl #1)
     2965        __(rsbcs d,d,#0)
     2966        __(rsbmi r,r,#0)
     2967        __(return_lisp_frame(imm2))
     2968popdef(`sign')
     2969popdef(`d',)
     2970popdef(`r',)               
     2971       
     2972       
     2973                       
     2974                       
    28582975
    28592976/*  EOF, basically  */
Note: See TracChangeset for help on using the changeset viewer.