|
|
1.1 ! root 1: /* Copyright 1989 by AT&T Bell Laboratories */ ! 2: #include "tags.h" ! 3: #include "prof.h" ! 4: #include "prim.h" ! 5: #define String(handle,len,str) .align 2;\ ! 6: .double len*power_tags+tag_string;\ ! 7: handle: .ascii str ! 8: /* args come in as ! 9: r2 = closure; can be ignored because contains no free vars ! 10: r0 = arg ! 11: r1 = continuation ! 12: ! 13: registers 0-4 can contain only pointers or tagged integers ! 14: register 5 is ptrtemp, and it could be anything?!? ! 15: registers 6-7 can contain anything except pointers ! 16: 4(sb) is the store pointer ! 17: fp is the data ptr ! 18: 0(sb) is the exception handler ! 19: sp is the stack pointer (mostly unused) ! 20: pc is the program counter ! 21: sb is the base address for the exception handler and store pointer ! 22: mod is the base address for sb ! 23: */ ! 24: #define Closure(name) .align 2;\ ! 25: .double mak_desc(1,tag_record);\ ! 26: name: .double .L/**/name/**/code;\ ! 27: .double 1;\ ! 28: .double tag_backptr;\ ! 29: .L/**/name/**/code: ! 30: ! 31: .text ! 32: .globl _mlmodreg ! 33: .align 2 ! 34: _mlmodreg: ! 35: .double _mlsbreg ! 36: .data ! 37: _saved_cmodreg: ! 38: .double 0 /* keep C happy, just in case */ ! 39: _saved_csbreg: ! 40: .double 0 ! 41: .globl _mlsbreg ! 42: _mlsbreg: ! 43: .double 0 /* exnptr */ ! 44: .double 0 /* storeptr */ ! 45: .text ! 46: /* Aligned strings for floating point exceptions */ ! 47: String(.Loflw,8,"overflow") ! 48: String(.Luflw,9,"underflow\0\0\0") ! 49: .globl _runvec ! 50: .align 2 ! 51: .double mak_desc(8,tag_record) ! 52: _runvec: ! 53: .double _array_v ! 54: .double _callc_v ! 55: .double _create_b_v ! 56: .double _create_s_v ! 57: .double _floor_v ! 58: .double _logb_v ! 59: .double _scalb_v ! 60: .double _syscall_v ! 61: ! 62: Closure(_array_v) ! 63: movd 0(r0),r6 /* r6 = ML_int(length) */ ! 64: ashd $-1,r6 /* r6 = length */ ! 65: movd 4(r0),r2 /* r2 = initial value */ ! 66: movd r6,r7 ! 67: ashd $width_tags,r7 ! 68: ord $tag_array,r7 /* r7 = proper tag for array */ ! 69: movzbd $0,-4(fp)[r6:d] /* allocate (maybe fault) */ ! 70: movd r7,-4(fp) /* set array tag */ ! 71: sprd fp,r0 /* return value is array start */ ! 72: addr 4(fp)[r6:d],r5 /* r5 = new freespace pointer */ ! 73: br .Ltest ! 74: .Ltop: movd r2,0(fp)[r6:d] /* store default at array sub r6 */ ! 75: .Ltest: acbd $-1,r6,.Ltop ! 76: movd r2,0(fp) /* store default at array sub 0 */ ! 77: lprd fp,r5 /* update freespace pointer */ ! 78: movd 0(r1),r5 /* r5 = code pointer for cont */ ! 79: jump 0(r5) ! 80: ! 81: Closure(_create_b_v) ! 82: movd $tag_bytearray,r4 ! 83: br .Lcre ! 84: Closure(_create_s_v) ! 85: movd $tag_string,r4 ! 86: .Lcre: addr 13(r0),r7 /* r0 = ML_int(length) */ ! 87: ashd $-3,r7 /* r7 = (length + 7) div 4 */ ! 88: movd r7,r6 ! 89: ashd $2,r6 /* r6 = bytes in string including tag */ ! 90: addqd $-1,r7 /* r7 = words in string, not including tag */ ! 91: movzbd $0,-4(fp)[r7:d] /* allocate (maybe fault) */ ! 92: movd r0,r7 ! 93: ashd $-1,r7 /* r7 = length */ ! 94: ashd $width_tags,r7 ! 95: ord r4,r7 ! 96: movd r7,-4(fp) /* install new tag */ ! 97: sprd fp,r0 /* return value is start of object */ ! 98: addr 0(fp)[r6:b],r5 ! 99: lprd fp,r5 /* uptdate freespace pointer */ ! 100: movd 0(r1),r5 ! 101: jump 0(r5) ! 102: ! 103: .globl _saveregs ! 104: .globl _handle_c ! 105: .globl _return_c ! 106: .globl _restoreregs ! 107: Closure(_handle_c) ! 108: movd $CAUSE_EXN,_cause; ! 109: br _saveregs ! 110: Closure(_return_c) ! 111: movd $CAUSE_RET,_cause; ! 112: _saveregs: ! 113: addr -4(fp),_saved_dataptr ! 114: movd 0(sb),_saved_exnptr ! 115: movd 4(sb),_saved_storeptr ! 116: movd r0,_saved_ptrs ! 117: movd r1,_saved_ptrs+4 ! 118: movd r2,_saved_ptrs+8 ! 119: movd r3,_saved_ptrs+12 ! 120: movd r4,_saved_ptrs+16 ! 121: movd r5,_saved_nonptrs ! 122: movd r6,_saved_nonptrs+4 ! 123: movd r7,_saved_nonptrs+8 ! 124: lprd sp,_bottom ! 125: lprd fp,_fpsave ! 126: lprw mod,_saved_cmodreg ! 127: lprd sb,_saved_csbreg ! 128: exit [r0,r1,r2,r3,r4,r5,r6,r7] ! 129: ret $0 ! 130: ! 131: _restoreregs: ! 132: /* .word 0x4000 /* What is this for on the VAX??? */ ! 133: /* Is it the register mask, for C calls? */ ! 134: enter [r0,r1,r2,r3,r4,r5,r6,r7],$0 ! 135: sprd fp,_fpsave ! 136: sprd sp,_bottom ! 137: sprd sb,_saved_csbreg ! 138: sprw mod,_saved_cmodreg ! 139: movd _saved_nonptrs,r5 ! 140: movd _saved_nonptrs+4,r6 ! 141: movd _saved_nonptrs+8,r7 ! 142: movd _saved_dataptr,r0 ! 143: addqd $4,r0 ! 144: lprd fp,r0 ! 145: addr _mlmodreg,r0 ! 146: lprw mod,r0 /* _mlmodreg had better be below 64K */ ! 147: lprd sb,0(r0) /* this will always be _mlsbreg */ ! 148: movd _saved_exnptr,0(sb) ! 149: movd _saved_storeptr,4(sb) ! 150: #ifdef BSD ! 151: movd $0,TOS ! 152: bsr ?_sigsetmask ! 153: adjspb $-4 ! 154: #endif ! 155: #ifdef V9 ! 156: bsr ?_setupsignals ! 157: #endif ! 158: movd _saved_ptrs,r0 ! 159: movd _saved_ptrs+4,r1 ! 160: movd _saved_ptrs+8,r2 ! 161: movd _saved_ptrs+12,r3 ! 162: movd _saved_ptrs+16,r4 ! 163: go: movd _saved_pc,tos ! 164: ret $0 ! 165: ! 166: /* Floating exceptions raised (assuming ROP's are never passed to functions): ! 167: * DIVIDE BY ZERO - (div) ! 168: * OVERFLOW/UNDERFLOW - (add,div,sub,mul) as appropriate ! 169: * ! 170: * floor raises integer overflow if the float is out of 32-bit range, ! 171: * so the float is tested before conversion, to make sure it is in (31-bit) ! 172: * range */ ! 173: ! 174: Closure(_floor_v) ! 175: floorld 0(r0),r6 ! 176: ashd $1,r6 ! 177: ord $1,r6 ! 178: movd r6,r0 ! 179: movd 0(r1),r5 ! 180: jump 0(r5) ! 181: ! 182: /* ! 183: * I don't know whether this routine is supposed to get ! 184: * the log base 2, or one more than that. ! 185: * On the Vax, it seems to do the latter, although in ! 186: * my port to the Sony, it does the former. ! 187: */ ! 188: Closure(_logb_v) ! 189: movd 4(r0),r6 /* Second half, containing exponent */ ! 190: bicd $0x800fffff,r6 /* grab only the exponent */ ! 191: ashd $-19,r6 /* move into position */ ! 192: subd $2046,r6 /* unbias */ ! 193: ord $1,r6 /* convert to ML int */ ! 194: movd r6,r0 /* give as arg to cont */ ! 195: movd 0(r1),r5 /* follow cont */ ! 196: jump 0(r5) ! 197: ! 198: Closure(_scalb_v) ! 199: /* args: float and incr */ ! 200: movd 4(r0),r6 ! 201: bicd $1,r6 /* grab add value */ ! 202: cmpqd $0,r6 ! 203: beq .Lnoth /* 0? */ ! 204: ashd $3,r6 /* shift to exponent field */ ! 205: movd 0(r0),r0 /* grab old float */ ! 206: movd 4(r0),r7 ! 207: bicd $0x800fffff,r7 /* grab exponent */ ! 208: ashd $-16,r7 /* move to vax exp field */ ! 209: addd r6,r7 /* check out the new exponent */ ! 210: cmpd r7,$0 ! 211: ble under /* too small? */ ! 212: cmpd r7,$0x8000 ! 213: bge over /* too large? */ ! 214: ashd $16,r6 /* move to ns32 exp field */ ! 215: addd 4(r0),r6 ! 216: movd r6,4(fp) /* place second half of float */ ! 217: movd 0(r0),0(fp) /* place first half of float */ ! 218: movd $mak_desc(8,tag_string),-4(fp) /* place tag */ ! 219: sprd fp,r0 /* return value is new float */ ! 220: addr 12(fp),r5 /* update freespace pointer */ ! 221: lprd fp,r5 ! 222: movd 0(r1),r5 /* follow cont */ ! 223: jump 0(r5) ! 224: .Lnoth: movd 0(r0),r0 /* return original float */ ! 225: movd 0(r1),r5 /* follow cont */ ! 226: jump 0(r5) ! 227: over: movzbd $0,4(fp) /* make space */ ! 228: addr .Loflw,r0 ! 229: br _raise_real ! 230: under: movzbd $0,4(fp) /* make space */ ! 231: addr .Luflw,r0 ! 232: br _raise_real ! 233: ! 234: _raise_real: ! 235: /* Danger: syntax of the C macro _real_e may matter here! */ ! 236: addr _real_e,4(fp) /* allocate arg record for exception */ ! 237: movd r0,0(fp) ! 238: movd $mak_desc(2,tag_record),-4(fp) ! 239: sprd fp,r0 /* arg to handler is exception value */ ! 240: addr 12(fp),r5 ! 241: lprd fp,r5 /* update freespace pointer */ ! 242: movd 0(sb),r1 /* get handler's cont */ ! 243: movd 0(r1),r5 /* jump to handler */ ! 244: jump 0(r5) ! 245: ! 246: Closure(_syscall_v) /* ARGS: call#, arglist, argcount */ ! 247: movzbd $0,20(fp) /* ensure enough space */ ! 248: movd 8(r0),r6 ! 249: ashd $-1,r6 /* r6 = argcount */ ! 250: movzbd $0,r7 /* r7 = 0 */ ! 251: movd 4(r0),r4 /* r4 = arglist */ ! 252: .Largloop: ! 253: cmpqd $0,r6 ! 254: bge .Largdone ! 255: addqd $-1,r6 ! 256: addqd $1,r7 ! 257: movd 0(r4),r2 /* r2 = hd(r4) */ ! 258: movd 4(r4),r4 /* r4 = tl(r4) */ ! 259: tbitb $0,r2 /* test tag bit of r2 */ ! 260: bfs .Largint ! 261: movd r2,0(fp)[r7:d] /* place arg */ ! 262: br .Largloop ! 263: .Largint: ! 264: movd r2,r5 /* convert from ML to C int */ ! 265: ashd $-1,r5 ! 266: movd r5,0(fp)[r7:d] /* place arg */ ! 267: br .Largloop ! 268: .Largdone: ! 269: movd 8(r0),r5 ! 270: ashd $-1,r5 ! 271: movd r5,0(fp) /* place argcount */ ! 272: movd 0(r0),r0 /* ML int call# */ ! 273: ashd $-1,r0 /* call# in r0 */ ! 274: movd r1,r5 /* save our continuation */ ! 275: addr 4(fp),r1 /* addr of first arg in r1 */ ! 276: movzbd $0,r2 /* clear r2, why? */ ! 277: svc ! 278: bcs .Lsyslose ! 279: addd r0,r0 /* convert result to ML int */ ! 280: addqd $1,r0 ! 281: movd r5,r1 /* restore cont */ ! 282: movd 0(r1),r5 /* follow cont */ ! 283: jump 0(r5) ! 284: .Lsyslose: ! 285: movd r0,_errno ! 286: movd $-1,r0 /* system call lost */ ! 287: movd r5,r1 /* restore cont */ ! 288: movd 0(r1),r5 /* follow cont */ ! 289: jump 0(r5) ! 290: ! 291: Closure(_callc_v) ! 292: movd r1,TOS ! 293: movd 4(r0),TOS ! 294: movd 0(r0),r5 ! 295: lprw mod,_saved_cmodreg /* keep C happy, just in case */ ! 296: lprd sb,_saved_csbreg ! 297: jsr 0(r5) /* call C routine */ ! 298: adjspb $-4 /* pop single C arg */ ! 299: addr _mlmodreg,r5 /* put ml mod and sb back */ ! 300: lprw mod,r5 ! 301: lprd sb,0(r5) ! 302: movd TOS,r1 ! 303: movzbd $0,r2 ! 304: movzbd $0,r3 ! 305: movzbd $0,r4 ! 306: movzbd $0,r5 ! 307: cmpqd $0,_cause ! 308: bne _saveregs ! 309: movd 0(r1),r5 ! 310: jump 0(r5) ! 311: ! 312: /* this bogosity is for export.c */ ! 313: .globl _startptr ! 314: _startptr: .double start
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.