|
|
1.1 ! root 1: #include "../h/config.h" ! 2: /* ! 3: * pret - returns a value from an Icon procedure. pret takes ! 4: * a single argument which is the value to return. The real ! 5: * work is in figuring out whether the return value needs to ! 6: * be dereferenced. ! 7: */ ! 8: ! 9: Global(_deref) /* Dereference a variable */ ! 10: Global(_rtrace) /* Return trace routine */ ! 11: Global(_boundary) /* Icon/C boundary address */ ! 12: Global(_current) /* Current expression stack */ ! 13: Global(_file) /* Current file name */ ! 14: Global(_k_level) /* Value of &level */ ! 15: Global(_k_trace) /* Value of &trace */ ! 16: Global(_line) /* Current line number */ ! 17: ! 18: Global(_pret) ! 19: #ifdef VAX ! 20: _pret: ! 21: Mask 0 # Don't need to save any registers because ! 22: # the current frame will be discarded. ! 23: movl fp,_boundary # The boundary is set because deref may ! 24: # cause garbage collection. ! 25: decl _k_level # A procedure is being exited, so &level ! 26: # must be decremented. ! 27: /* ! 28: * Calculate target address for return value in r11. ! 29: */ ! 30: # The frame of the caller is the procedure ! 31: # frame for the Icon procedure returning ! 32: movl 8(fp),r2 # a value. Put it's ap in r2. ! 33: # The return value will overwrite arg0, ! 34: # the address of arg0 is calculated via: ! 35: ashl $3,4(r2),r11 # r11 = 8 * nargs ! 36: addl2 $8,r11 # + 8 ! 37: addl2 r2,r11 # + ap ! 38: # Note that nargs and ap belong to the ! 39: # returning Icon procedure. ! 40: /* ! 41: * Dereference the return value if it is a local variable or an ! 42: * argument. ! 43: */ ! 44: # The return value is on the stack as ! 45: # an argument, put type field of return ! 46: movl 8(ap),r1 # value in r1 for testing. ! 47: bitl $F_NQUAL,r1 # If return value is a string, ! 48: beql chktrace # it doesn't need dereferencing. ! 49: bitl $F_VAR,r1 # If return value isn't a variable, ! 50: beql chktrace # it doesn't need dereferencing. ! 51: bitl $F_TVAR,r1 # If return value is a trapped variable, ! 52: bneq chktv # it requires some work. ! 53: movl 12(ap),r1 # Otherwise, get the address of the ! 54: jmp chkloc # data block for more testing. ! 55: ! 56: chktv: # A trapped variable is being returned, ! 57: # only substring trapped variables need ! 58: # dereferencing. ! 59: bicl2 $~TYPEMASK,r1 # "and" off all but bits in type field ! 60: cmpl $T_TVSUBS,r1 # If the variable isn't a substring t.v., ! 61: bneq chktrace # it doesn't need dereferencing. ! 62: movl 12(ap),r1 # Point r1 at data block for s.s.t.v. ! 63: movl 16(r1),r1 # Then at actual address of variable ! 64: chkloc: # ! 65: # See if the variable is on the stack. ! 66: # If it is, it will lie between the ! 67: # sp and the base of the current ! 68: # expression stack. r1 holds address ! 69: # of variable. ! 70: cmpl r1,sp # If address is below the sp, ! 71: blssu chktrace # it's not a local or an argument ! 72: movl _current+4,r0 # Point r0 at data block for current ! 73: # expression. ! 74: cmpl r1,12(r0) # Fourth word is the base of the stack ! 75: # for the current expression. If the ! 76: # variable address is above the stack ! 77: bgtru chktrace # base, it's not a local or an argument. ! 78: # Otherwise, it is a local or an argument ! 79: # and must be dereferenced. ! 80: pushal 8(ap) # Push address of return value ! 81: calls $1,_deref # and dereference it. ! 82: ! 83: /* ! 84: * Print trace message if &trace is set. ! 85: */ ! 86: chktrace: ! 87: tstl _k_trace # If &trace is zero, ! 88: beql tracedone # no tracing. ! 89: # Otherwise, set up to call rtrace ! 90: # with address of proc block and ! 91: # return value. ! 92: pushal 8(ap) # Push address of return value ! 93: pushl 4(r11) # Push address of procedure block ! 94: calls $2,_rtrace # rtrace(proc. block address,&return value) ! 95: ! 96: tracedone: # The descriptor for the procedure block ! 97: # (arg0) must be replaced by the descriptor ! 98: # of the return value. r11 points at the ! 99: movq 8(ap),(r11) # procedure block, so a movq does the trick. ! 100: /* ! 101: * Return from the Icon procedure. What this really does is to return ! 102: * via the frame built by invoke. Thus, the return below returns from ! 103: * the call to invoke. ! 104: */ ! 105: ! 106: movl 12(fp),fp # Get frame built by invoke on top of stack ! 107: movl -4(fp),_line # Restore _line, ! 108: movl -8(fp),_file # and _file from procedure block. ! 109: clrl _boundary # Reentering an Icon environment, so ! 110: # the boundary is cleared. ! 111: ret # Return. This is manifested as a ! 112: # return from invoke. ! 113: #endif VAX ! 114: ! 115: #ifdef PORT ! 116: DummyFcn(_pret) ! 117: #endif PORT ! 118: #ifdef PDP11 ! 119: / pret - return from an Icon procedure. ! 120: / Return value is argument to pret at 6(r5). ! 121: ! 122: / Register usage: ! 123: / r1: type or pointer field of returned value ! 124: / r2: returning procedure frame pointer ! 125: / r3: address of argument #0 (place-holder for returned value) ! 126: / r5: current procedure frame pointer ! 127: _pret: ! 128: mov r5,-(sp) / create new procedure frame ! 129: mov sp,r5 ! 130: mov r4,-(sp) ! 131: mov r3,-(sp) ! 132: mov r2,-(sp) ! 133: mov r5,_boundary / set Icon/C boundary ! 134: ! 135: / Decrement &level and calculate address of eventual return value. ! 136: ! 137: dec _k_level ! 138: mov (r5),r2 / compute address for ! 139: mov 4(r2),r3 / return value: ! 140: asl r3 / r3 = r2 + 6 + 4*nargs ! 141: asl r3 ! 142: add r2,r3 ! 143: add $6,r3 ! 144: ! 145: / Dereference return value if necessary. ! 146: ! 147: mov 6(r5),r1 / get type field of return value into r1 ! 148: bit $F_NQUAL,r1 / if return value is the ! 149: beq 1f / name of a local variable ! 150: bit $F_VAR,r1 / or argument, then it ! 151: beq 1f / needs dereferencing ! 152: bit $F_TVAR,r1 ! 153: bne 2f ! 154: mov 8.(r5),r1 / get pointer field into r1 ! 155: br 3f ! 156: 2: ! 157: bic $!TYPEMASK,r1 / check type code for substring t.v. ! 158: cmp $T_TVSUBS,r1 / if not, it doesn't need ! 159: bne 1f / dereferencing ! 160: mov 8.(r5),r1 / get pointer field from b_tvsubs ! 161: mov 8.(r1),r1 / block into r1 ! 162: 3: ! 163: cmp r1,sp / if pointer is between ! 164: blo 1f / sp and sbase, it is a local ! 165: mov _current+2,r0 / or an argument ! 166: cmp r1,6(r0) ! 167: bhi 1f ! 168: mov r5,-(sp) / dereference it ! 169: add $6,(sp) ! 170: jsr pc,_deref ! 171: tst (sp)+ ! 172: ! 173: / Print trace message if &trace is set. ! 174: ! 175: 1: ! 176: tst _k_trace ! 177: beq 1f ! 178: mov r5,-(sp) / push address of return value ! 179: add $6,(sp) ! 180: mov 2(r3),-(sp) / push pointer to procedure block ! 181: jsr pc,_rtrace / call rtrace; other arguments are in frame ! 182: cmp (sp)+,(sp)+ ! 183: ! 184: / Copy return value to the outer expression frame. ! 185: ! 186: 1: ! 187: mov r3,r1 / save r3 to pop stack to this point later ! 188: mov 6(r5),(r3)+ / move return value down from top of stack ! 189: mov 8.(r5),(r3) ! 190: ! 191: / Return. ! 192: ! 193: mov r2,r5 / restore old values of registers ! 194: mov r2,r0 ! 195: mov -(r0),r4 ! 196: mov -(r0),r3 ! 197: mov -(r0),r2 ! 198: mov -(r0),_line ! 199: mov -(r0),_file ! 200: mov r5,sp ! 201: mov (sp)+,r5 ! 202: mov (sp)+,r0 / pop return pc ! 203: mov r1,sp / pop stack to return value ! 204: clr _boundary / clear Icon/C boundary ! 205: jmp (r0) / return ! 206: #endif PDP11
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.