|
|
1.1 root 1: /*
2: * This routine sets the addressing flags for a tree node.
3: * This version is for both the SMALL and LARGE model iAPX-86.
4: * There is no provision for double indexed address modes;
5: * the compiler does not attempt to use them at this time.
6: */
7: #ifdef vax
8: #include "INC$LIB:cc1.h"
9: #else
10: #include "cc1.h"
11: #endif
12:
13: TREE *findoffs();
14:
15: /*
16: * Determine access mode.
17: * The mode set is stored into the 't_flag' field.
18: * The subtrees have already been marked.
19: * Knows how the output writer will map
20: * the logical segments into physical segments.
21: * This routine is usually called by 'walk'.
22: */
23: amd(tp, ptp)
24: register TREE *tp;
25: TREE *ptp;
26: {
27: register TREE *xp;
28: register ival_t half;
29: register int op;
30: register REGNAME r;
31: register FLAG flag;
32: register FLAG mask;
33: register KIND kind;
34: register TYPE t;
35: register lval_t n;
36: register int i;
37: register int seg;
38:
39: if ((op=tp->t_op) == LEAF) {
40: tp->t_flag = tp->t_lp->t_flag;
41: return;
42: }
43: flag = 0;
44: if (op==ICON || op==LCON) {
45: if ((n=grabnval(tp)) == 0)
46: flag |= T_0;
47: else if (n == 1)
48: flag |= T_1;
49: else if (n == 2)
50: flag |= T_2;
51: if (n>=-128 && n<=127)
52: flag |= T_BYTE;
53: if (op == LCON) {
54: flag |= T_LCN;
55: half = lower(n);
56: if (half == 0)
57: flag |= T_LHC;
58: if (half == -1)
59: flag |= T_LHS;
60: half = upper(n);
61: if (half == 0)
62: flag |= T_UHC;
63: if (half == -1)
64: flag |= T_UHS;
65: } else
66: flag |= T_ICN;
67: }
68: if (op == DCON) {
69: flag |= T_DCN;
70: i = 0;
71: while (i<sizeof(dval_t) && tp->t_dval[i]==0)
72: ++i;
73: if (i == sizeof(dval_t))
74: flag |= T_0;
75: }
76: if (op == REG) {
77: flag |= T_DIR;
78: kind = pertype[tp->t_type].p_kind;
79: if ((reg[tp->t_reg].r_lvalue&kind) != 0)
80: flag |= T_LREG;
81: if ((reg[tp->t_reg].r_rvalue&kind) != 0)
82: flag |= T_RREG;
83: #if !ONLYSMALL
84: if (tp->t_reg==SSSP || tp->t_reg==SSBP)
85: flag |= T_SREG;
86: #endif
87: } else if (op == ADDR) {
88: if (isvariant(VSMALL))
89: flag |= T_ADS;
90: else {
91: xp = tp->t_lp;
92: if (xp->t_op==LID || xp->t_op==GID) {
93: switch (xp->t_seg) {
94: case SCODE:
95: case SLINK:
96: flag |= T_ACS;
97: break;
98: case SPURE:
99: if (isvariant(VRAM))
100: flag |= T_ADS;
101: else
102: flag |= T_ACS;
103: break;
104: case SSTRN:
105: if (notvariant(VROM))
106: flag |= T_ADS;
107: else
108: flag |= T_ACS;
109: break;
110: case SDATA:
111: case SBSS:
112: flag |= T_ADS;
113: break;
114: }
115: }
116: }
117: } else if (op==LID || op==GID) {
118: #if ONLYSMALL
119: flag |= T_DIR;
120: #else
121: seg = tp->t_seg;
122: if (isvariant(VSMALL)
123: || (ptp!=NULL && ptp->t_op==CALL && tp==ptp->t_lp)
124: || seg==SCODE
125: || seg==SLINK
126: || (seg==SPURE && notvariant(VRAM)))
127: flag |= T_DIR;
128: #endif
129: } else if ((op==ADD || op==SUB) && ispoint(t=tp->t_type)) {
130: mask = T_CON;
131: if (op == SUB)
132: mask = T_NUM;
133: xp = tp;
134: do {
135: if ((xp->t_rp->t_flag&mask) == 0)
136: break;
137: xp = xp->t_lp;
138: } while (xp->t_op==ADD || xp->t_op==SUB);
139: if ((xp->t_flag&T_REG) != 0) {
140: while (xp->t_op == LEAF)
141: xp = xp->t_lp;
142: r = xp->t_reg;
143: #if !ONLYSMALL
144: if (notvariant(VSMALL)) {
145: if (r == SSBP)
146: flag |= T_LSS;
147: } else {
148: #endif
149: if (r==SI || r==DI || r==BX || r==BP)
150: flag |= T_LEA;
151: #if !ONLYSMALL
152: }
153: #endif
154: }
155: } else if (op == STAR) {
156: xp = findoffs(tp);
157: if ((xp->t_flag&T_CON) != 0 && notvariant(VLARGE))
158: flag |= T_DIR;
159: else if ((xp->t_flag&T_REG) != 0) {
160: while (xp->t_op == LEAF)
161: xp = xp->t_lp;
162: r = xp->t_reg;
163: #if !ONLYSMALL
164: if (notvariant(VSMALL)) {
165: if (r==SSBP
166: || r==ESSI || r==ESDI || r==ESBX
167: || r==DSSI || r==DSDI || r==DSBX)
168: flag |= T_DIR;
169: } else {
170: #endif
171: if (r==BP
172: || r==SI || r==DI || r==BX)
173: flag |= T_DIR;
174: #if !ONLYSMALL
175: }
176: #endif
177: }
178: flag |= T_OFS;
179: }
180: tp->t_flag = flag;
181: }
182:
183: /*
184: * Given a pointer to an offset type
185: * tree, run down the chain of indirections
186: * and additions, looking for the tree that
187: * must be loaded into a register to get
188: * an addressable tree. Return a pointer to
189: * this tree.
190: */
191: TREE *
192: findoffs(tp)
193: register TREE *tp;
194: {
195: register flag, ct=0, op;
196:
197: while (tp->t_op == LEAF)
198: tp = tp->t_lp;
199: for (;;) {
200: tp = tp->t_lp;
201: switch (op=tp->t_op) {
202: case SUB: /* can't load neg addr */
203: if(tp->t_rp->t_flag&T_NUM)
204: break;
205: return tp;
206: case ADD: /* add one addr max */
207: if((flag=(tp->t_rp->t_flag))&T_NUM)
208: break;
209: else
210: if(flag&T_CON&&0==ct++)
211: break;
212: default:
213: return tp;
214: }
215: }
216: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.