|
|
1.1 root 1: (* Copyright 1989 by AT&T Bell Laboratories *)
2: functor NS32CM(V : NS32CODER) : CMACHINE = struct
3:
4: structure V' : sig datatype Register = Genreg of int
5: | FloatReg of int
6: | FP
7: | SP
8: | SB
9: | PC
10:
11: eqtype Label sharing type Label = V.Label
12: datatype Size = Byte | Word | Long
13:
14: datatype EA = Direct of Register
15: | Topofstack
16: | Displace of int * Register
17: | Immed of int
18: | Immedlab of Label
19: | Abs of int
20: | OffAddress of Label * int
21: | Index of EA * Register * Size
22:
23: end = V
24: open V' System.Tags
25:
26: datatype condition = NEQ | EQL | LEQ | GEQ | LSS | GTR
27:
28: fun address lab = OffAddress(lab,0) (* old Address style *)
29:
30: fun defer(Direct r) = Displace(0,r)
31: | defer(Immedlab lab) = address lab
32: | defer(Displace z) = ErrorMsg.impossible "defer of displace in cpsns32"
33: | defer _ = ErrorMsg.impossible "defer in cpsns32"
34:
35: val sp' = SP
36: val exnptr = Displace(0, SB)
37: val dataptr as Direct dataptr' = Direct(FP)
38: val arithtemp as Direct arithtemp' = Direct(Genreg 6)
39: val arithtemp2 = Direct(Genreg 7)
40: val storeptr = Displace(4, SB)
41: val standardclosure = Direct(Genreg 2)
42: val standardarg = Direct(Genreg 0)
43: val standardcont = Direct(Genreg 1)
44: val miscregs : EA list = map (Direct o Genreg) [3,4]
45: val ptrtemp = Direct(Genreg 5)
46:
47: fun newlabel() = Immedlab(V.newlabel())
48: fun emitlab(i,Immedlab lab) = V.emitlab(i,lab)
49: fun define (Immedlab lab) = V.define lab
50: fun beginStdFn _ = ()
51:
52: val align = V.align
53: val mark = V.mark
54:
55: fun move(Immedlab l, dest as Direct(Genreg x)) = V.lea(address l, dest)
56: | move(Immedlab l, dest) = (* This via ptrtemp probably not needed BUGBUG *)
57: (V.lea(address l, ptrtemp);
58: move(ptrtemp, dest))
59: (* Only runtime knows about SB and MOD registers.
60: We use SB as a base for our pseudo-registers.
61: | move(src as Direct(SB), dest) = V.sprl(src, dest)
62: | move(src, dest as Direct(SB)) = V.lprl(src, dest)
63: *)
64: | move(src as Direct(FP), dest) = V.sprl(src, dest)
65: | move(src, dest as Direct(FP)) = V.lprl(src, dest)
66: | move x = V.movl x
67:
68: (* checkLimit (n):
69: * Generate code to check the heap limit to see if there is enough free space
70: * to allocate n bytes.
71: *)
72: fun checkLimit maxAllocSize = (
73: V.comment ("begin fun, max alloc = "^(makestring maxAllocSize)^"\n");
74: (* Check the heap limit by writing to the dataptr+maxAllocSize-4 *)
75: move(Immed 0, Displace(maxAllocSize-4, dataptr')))
76:
77: val emitlong = V.emitlong
78: val realconst = V.realconst
79: val emitstring = V.emitstring
80:
81: fun jmpindexb lab = V.jump(Index(defer lab, arithtemp', Byte))
82:
83: fun record(vl, z) =
84: let open CPS
85: val len = List.length vl
86: fun f(i,nil) = ()
87: | f(i,(Direct r, SELp(j,p))::rest) = f(i,(Displace(j*4,r),p)::rest)
88: | f(i,(Immedlab l, p)::rest) = (V.lea(address l, ptrtemp);
89: f(i, (ptrtemp,p)::rest))
90: | f(i,(x,OFFp 0)::rest) = (move(x,Displace(i*4,dataptr'));
91: f(i-1,rest))
92: | f(i,(Direct r, OFFp j)::rest) = (V.lea(Displace(j*4,r),
93: Displace(i*4,dataptr'));
94: f(i-1,rest))
95: | f(i,(x,p)::rest) = (move(x,ptrtemp); f(i,(ptrtemp,p)::rest))
96: in
97: f(len - 2, rev vl);
98: move(dataptr,z);
99: V.lea(Displace(4*len, dataptr'), ptrtemp);
100: move(ptrtemp, dataptr)
101: (* V.addl(Immed(4*len), dataptr) *)
102: end
103:
104: fun select(i, Direct r, s) = move(Displace(i*4,r),s)
105: | select(0, a, s) = move(defer a, s) (* BUGBUG *)
106:
107: fun offset(i, Direct r, s) = V.lea(Displace(i*4,r),s)
108:
109: exception Three
110: fun three opcode (a,b,c) =
111: if b=c then opcode(a,b)
112: else if a=c then (move(a,ptrtemp); three opcode(ptrtemp,b,c))
113: else (move(b,c); opcode(a,c))
114:
115: (* opcode is commutative *)
116: fun threec opcode (a,b,c) =
117: if b=c then opcode(a,c)
118: else if a=c then opcode(b,c)
119: else (move(b,c); opcode(a,c))
120:
121: (* opcode(x,y) is bop(y,anti(x)) *)
122: fun threeab opcode anti bop (a,b,c) =
123: if b=c then opcode(a,c)
124: else if a=c then (anti(c,c); bop(b,c))
125: else (move(b,c); opcode(a,c))
126:
127: (* The use of three here is silly.
128: If opcode is commutative, then only one move should ever
129: be necessary, not two, as in the middle case of above.
130: Also note that we have few registers, so folding is likely.
131: The only non-commutative 3-operation here is subl3.
132: Subtraction may require a move, but in this case we should
133: do a negate instead of a move, then add.
134: *)
135:
136: val addl3 = threec V.addl
137: val addl3t = addl3
138: val subl3 = threeab V.subl V.negl V.addl
139: val subl3t = subl3
140: fun ashl(s, r, d as Direct(Genreg _)) =
141: (if r<>d then move(r,d) else ();
142: V.ashl(s,d))
143: fun ashr(Immed i, b, c) = ashl(Immed (~i), b, c)
144: | ashr(a,b,c) = (V.negl(a,ptrtemp);
145: ashl(ptrtemp,b,c))
146: val mull2 = V.mull
147: val mull2t = mull2
148: val divl2 = V.divl
149: val andb = threec V.andl
150: val orb = threec V.orl
151: val xorb = threec V.xorl
152: fun notb (a,b) = V.coml(a,b)
153:
154: fun fetchindexl(Direct x,y,Immed k) = move(Displace(k+k-2,x),y)
155: | fetchindexl(Direct x,y,Direct z) = move(Index(Displace(~2,x),z,Word),y)
156: | fetchindexl(Immedlab lab, y, Direct z) =
157: move(Index(OffAddress(lab,~2), z, Word), y)
158: fun storeindexl(x,y, Immed 1) = move(x, defer y)
159: | storeindexl(x, Direct y, Immed k) = move(x, Displace(k+k-2,y))
160: | storeindexl(x, Direct y, Direct z) = move(x,Index(Displace(~2,y),z,Word))
161: fun fetchindexb(v,w) = V.movzbl(Index(defer v, arithtemp', Byte),w)
162: fun storeindexb(v,w) = V.movb(v,Index(defer w, arithtemp', Byte))
163:
164: fun finishreal(y) = (V.movl(Immed(8*power_tags + tag_string),
165: Displace(~4,dataptr'));
166: move(dataptr,y);
167: V.lea(Displace(4*3, dataptr'), ptrtemp);
168: move(ptrtemp, dataptr))
169: (* V.addl(Immed(4*3), dataptr)) *)
170:
171: val fp0 = FloatReg 0
172:
173: fun float f (a,b,c) =
174: (V.movg(defer a, Direct fp0);
175: f(defer b, Direct fp0);
176: V.movg(Direct fp0, defer dataptr);
177: finishreal c)
178:
179: fun mnegg(x,y) = (V.negg(defer x, defer dataptr); finishreal y)
180:
181: val mulg3 = float V.mulg
182: val divg3 = float V.divg
183: val addg3 = float V.addg
184: val subg3 = float V.subg
185:
186: fun cbranch NEQ = V.bne
187: | cbranch EQL = V.beq
188: | cbranch LEQ = V.ble
189: | cbranch GEQ = V.bge
190: | cbranch LSS = V.blt
191: | cbranch GTR = V.bgt
192:
193: fun ibranch (cond, op1, op2, label) =
194: (V.cmpl(op1, op2); cbranch cond (defer label))
195:
196: fun gbranch (cond, op1, op2, label) =
197: (V.cmpg(defer op1, defer op2); cbranch cond (defer label))
198:
199: fun defer' j = fn x => j(defer x)
200: val jmp = defer' V.jump
201: val bbs = fn(x,y,l) => (V.tbit(x,y); V.bfs(defer l))
202:
203: val immed = Immed
204: fun isimmed(Immed i) = SOME i
205: | isimmed _ = NONE
206:
207: fun isreg(Direct(Genreg i)) = SOME i
208: (* | isreg(Direct(FP)) = SOME(8) (* What? BUGBUG *) *)
209: | isreg _ = NONE
210:
211: fun eqreg (a: EA) b = a=b
212:
213: fun profile(i,incr) = if i >= Profile.PROFSIZE
214: then ErrorMsg.impossible ("Bad profiling in ns32: trying "
215: ^makestring i^" with size "
216: ^makestring Profile.PROFSIZE)
217: else V.addl(Immed incr, Displace(4*i,sp')) (* MSPACE mode *)
218:
219: val comment = V.comment
220: end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.