|
|
1.1 root 1: (* Copyright 1989 by AT&T Bell Laboratories *)
2: functor VaxCM(V : VAXCODER) : CMACHINE = struct
3:
4: structure V' : sig datatype Register = reg of int
5:
6: eqtype Label sharing type Label = V.Label
7: datatype EA = direct of Register
8: | autoinc of Register
9: | autodec of Register
10: | displace of int * Register
11: | deferred of int * Register
12: | immed of int
13: | immedlab of Label
14: | address of Label
15: | index of EA * Register
16:
17: end = V
18: open V' System.Tags
19:
20: datatype condition = NEQ | EQL | LEQ | GEQ | LSS | GTR
21:
22: fun defer(direct r) = displace(0,r)
23: | defer(displace z) = deferred z
24: | defer(immedlab lab) = address lab
25: | defer _ = ErrorMsg.impossible "defer in cpsvax"
26:
27: val sp' = reg 14
28: val exnptr = direct(reg 13)
29: val dataptr as direct dataptr' = direct(reg 12)
30: val datalimit = direct(reg 8)
31: val arithtemp as direct arithtemp' = direct(reg 9)
32: val arithtemp2 = direct(reg 10)
33: val storeptr = direct(reg 11)
34: val standardclosure = direct(reg 2)
35: val standardarg = direct(reg 0)
36: val standardcont = direct(reg 1)
37: val miscregs = map (direct o reg) [3,4,5,6,7]
38:
39: fun newlabel() = immedlab(V.newlabel())
40: fun emitlab(i,immedlab lab) = V.emitlab(i,lab)
41: fun define (immedlab lab) = V.define lab
42:
43: fun beginStdFn _ = ()
44:
45: (* checkLimit (n):
46: * Generate code to check the heap limit to see if there is enough free space
47: * to allocate n bytes.
48: *)
49: fun checkLimit maxAllocSize = (
50: V.comment ("begin fun, max alloc = "^(makestring maxAllocSize)^"\n");
51: if maxAllocSize <= 4096
52: then V.addl3(dataptr,datalimit,arithtemp)
53: else (V.addl3(dataptr,immed(maxAllocSize-4096+70),arithtemp);
54: (* the +70 in the line above is to force the immed literal to be stored
55: as a 5-byte addressing mode, rather than a 1-byte; this makes things
56: simpler for the runtime system *)
57: V.addl2(datalimit,arithtemp)))
58:
59: val align = V.align
60: val mark = V.mark
61: val move = V.movl
62: val emitlong = V.emitlong
63: val realconst = V.realconst
64: val emitstring = V.emitstring
65:
66: fun jmpindexb lab = V.jmp(index(defer lab, arithtemp'))
67:
68: fun record(vl, z) =
69: let open CPS
70: val len = List.length vl
71: fun f(i,nil) = ()
72: | f(i,(direct r, SELp(j,p))::rest) = f(i,(displace(j*4,r),p)::rest)
73: | f(i,z::(direct s, SELp(j,p))::rest) =
74: f(i,z::(displace(4*j,s),p)::rest)
75: | f(i,(x as direct(reg r), OFFp 0)::
76: (y0 as (y as direct(reg s), OFFp 0))::rest) =
77: if (s+1=r) then (V.movq(y,displace((i-1)*4,dataptr'));
78: f(i-2,rest))
79: else (V.movl(x,displace(i*4,dataptr')); f(i-1,y0::rest))
80: | f(i,(x as displace(j,r),OFFp 0)::(y as displace(k,s),OFFp 0)::rest) =
81: if k+4=j andalso r=s
82: then (V.movq(y,displace((i-1)*4,dataptr')); f(i-2,rest))
83: else (V.movl(x,displace(i*4,dataptr'));
84: f(i-1,(y,OFFp 0)::rest))
85: | f(i,(x,OFFp 0)::rest) = (V.movl(x,displace(i*4,dataptr'));
86: f(i-1,rest))
87: | f(i,(displace kr,SELp(0,p))::rest) = f(i,(deferred kr,p)::rest)
88: | f(i,(direct r, OFFp j)::rest) = (V.moval(displace(j*4,r),
89: displace(i*4,dataptr'));
90: f(i-1,rest))
91: | f(i,(x,p)::rest) = (V.movl(x,arithtemp); f(i,(arithtemp,p)::rest))
92: in f(len - 2, rev vl);
93: V.movl(dataptr,z);
94: V.addl2(immed(4*len), dataptr)
95: end
96:
97: fun select(i, direct r, s) = V.movl(displace(i*4,r),s)
98: | select(0, a, s) = V.movl(defer a, s)
99:
100: fun offset(i, direct r, s) = V.moval(displace(i*4,r),s)
101:
102: val addl3 = V.addl3
103: val addl3t = addl3
104: val subl3 = V.subl3
105: val subl3t = subl3
106: val ashl = V.ashl
107: fun ashr(immed i, b, c) = V.ashl(immed (~i), b, c)
108: | ashr(a,b,c) = (V.subl3(a,immed 0,arithtemp2);
109: (* potential bug, if generic is changed*)
110: V.ashl(arithtemp2,b,c))
111: val mull2 = V.mull2
112: val mull2t = mull2
113: val divl2 = V.divl2
114: val orb = V.bisl3
115: fun andb (a,b,c) = (V.subl3(a,immed ~1,arithtemp); (* potential bug, if
116: generic.sml is changed! *)
117: V.bicl3(arithtemp,b,c))
118: fun notb (a,b) = V.subl3(a,immed(~1),b)
119: val xorb = V.xorl3
120:
121: fun fetchindexl(v,w, immed 1) = V.movl(defer v, w)
122: | fetchindexl(direct v, w, immed k) = V.movl(displace(2*k-2,v), w)
123: | fetchindexl(v,w,i) =
124: (V.ashl(immed ~1,i,arithtemp);
125: V.movl(index(defer v, arithtemp'),w))
126: fun storeindexl(v,w, immed 1) = V.movl(v, defer w)
127: | storeindexl(v, direct w, immed k) = V.movl(v, displace(2*k-2, w))
128: | storeindexl(v,w,i) =
129: (V.ashl(immed ~1,i,arithtemp);
130: V.movl(v,index(defer w, arithtemp')))
131: fun fetchindexb(v,w) = V.movzbl(index(defer v, arithtemp'),w)
132: fun storeindexb(v,w) = V.movb(v,index(defer w, arithtemp'))
133:
134: fun finishreal(y) = (V.movl(immed(8*power_tags + tag_string),
135: displace(~4,dataptr'));
136: V.movl(dataptr,y);
137: V.addl2(immed(4*3), dataptr))
138:
139: fun mnegg(x,y) = (V.mnegg(defer x, defer dataptr); finishreal y)
140:
141: fun realop f = fn (a,b,c) => (f(defer a, defer b, defer dataptr);
142: finishreal c)
143: val mulg3 = realop V.mulg3
144: val divg3 = realop (fn (a,b,c) => V.divg3 (b,a,c))
145: val addg3 = realop V.addg3
146: val subg3 = realop (fn (a,b,c) => V.subg3 (b,a,c))
147:
148: fun cbranch NEQ = V.bneq
149: | cbranch EQL = V.beql
150: | cbranch LEQ = V.bleq
151: | cbranch GEQ = V.bgeq
152: | cbranch LSS = V.blss
153: | cbranch GTR = V.bgtr
154:
155: fun ibranch (cond, op1, op2, label) =
156: (V.cmpl(op1, op2); cbranch cond (defer label))
157:
158: fun gbranch (cond, op1, op2, label) =
159: (V.cmpg(defer op1, defer op2); cbranch cond (defer label))
160:
161: fun defer' j = fn x => j(defer x)
162: val jmp = defer' V.jmp
163: val bbs = fn(x,y,l) => V.bbs(x,y, defer l)
164:
165: fun isimmed(immed i) = SOME i
166: | isimmed _ = NONE
167:
168: fun isreg(direct(reg i)) = SOME i | isreg _ = NONE
169: fun eqreg (a: EA) b = a=b
170:
171: fun profile(i,incr) = if i >= Profile.PROFSIZE
172: then ErrorMsg.impossible ("Bad profiling in vax: trying "
173: ^makestring i^" with size "
174: ^makestring Profile.PROFSIZE)
175: else V.addl2(immed incr, displace(4*i,sp'))
176:
177: val comment = V.comment
178: end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.