|
|
1.1 root 1: /*
2: * n1/i386/amd.c
3: * Access mode determination.
4: * This routine sets the addressing flags for a tree node.
5: * There is no provision for double indexed address modes;
6: * the compiler does not attempt to use them at this time.
7: * i386.
8: */
9:
10: #ifdef vax
11: #include "INC$LIB:cc1.h"
12: #else
13: #include "cc1.h"
14: #endif
15:
16: TREE *findoffs();
17:
18: /*
19: * Determine access mode and store it into the 't_flag' field.
20: * The subtrees have already been marked.
21: * This routine is usually called by 'walk'.
22: */
23: amd(tp, ptp) register TREE *tp; TREE *ptp;
24: {
25: register FLAG flag;
26: register int op;
27: register TREE *xp;
28: register FLAG mask;
29: register lval_t n;
30: register int i;
31:
32: if ((op=tp->t_op) == LEAF) {
33: /* Leaf nodes inherit flags of subtree. */
34: tp->t_flag = tp->t_lp->t_flag;
35: return;
36: }
37: flag = 0;
38: if (op==ICON || op==LCON) { /* integer constants */
39: flag |= T_NUM;
40: if ((n = grabnval(tp)) >= 0) {
41: if (n == 0)
42: flag |= T_0|T_SHCNT|T_SBYTE|T_UBYTE|T_SWORD|T_UWORD;
43: else if (n == 1)
44: flag |= T_1|T_SHCNT|T_SBYTE|T_UBYTE|T_SWORD|T_UWORD;
45: else if (n <= 31)
46: flag |= T_SHCNT|T_SBYTE|T_UBYTE|T_SWORD|T_UWORD;
47: else if (n <= 127)
48: flag |= T_SBYTE|T_UBYTE|T_SWORD|T_UWORD;
49: else if (n <= 255)
50: flag |= T_UBYTE|T_SWORD|T_UWORD;
51: else if (n <= 32767L)
52: flag |= T_SWORD|T_UWORD;
53: else if (n <= 65535L)
54: flag |= T_UWORD;
55: } else {
56: if (n >= -128)
57: flag |= T_SBYTE|T_SWORD;
58: else if (n >= -32768L)
59: flag |= T_SWORD;
60: }
61: } else if (op == DCON) { /* double constants */
62: flag |= T_DCN;
63: for (i = 0; i < sizeof(dval_t) && tp->t_dval[i]==0; i++)
64: ;
65: if (i == sizeof(dval_t))
66: flag |= T_0;
67: } else if (op == REG) /* registers */
68: flag |= T_REG;
69: else if (op == ADDR) /* address of ... */
70: flag |= T_ADDR;
71: else if (op==LID || op==GID) /* identifiers */
72: flag |= T_DIR;
73: else if ((op == ADD || op == SUB) && ispoint(tp->t_type)) {
74: /* Check for effective address, e.g. %ebp+12 or &i+1. */
75: mask = (op == ADD) ? T_CON : T_NUM;
76: xp = tp;
77: do {
78: if ((xp->t_rp->t_flag & mask) == 0)
79: break;
80: xp = xp->t_lp;
81: } while (xp->t_op==ADD || xp->t_op==SUB);
82: if (isreg(xp))
83: flag |= T_LEA;
84: } else if (op == STAR) {
85: xp = findoffs(tp);
86: if ((xp->t_flag & T_CON) != 0 || isreg(xp))
87: flag |= T_DIR;
88: flag |= T_OFS;
89: }
90: tp->t_flag = flag;
91: }
92:
93: /*
94: * Given a pointer to an offset type tree, return a pointer to the tree
95: * that must be loaded into a register to get an addressable tree.
96: */
97: TREE *
98: findoffs(tp) register TREE *tp;
99: {
100: register flag, n;
101:
102: while (tp->t_op == LEAF)
103: tp = tp->t_lp;
104: for (n = 0;;) {
105: tp = tp->t_lp;
106: switch (tp->t_op) {
107: case SUB: /* can't load neg addr */
108: if (tp->t_rp->t_flag & T_NUM)
109: break;
110: return tp;
111: case ADD: /* add one addr max */
112: if ((flag = (tp->t_rp->t_flag)) & T_NUM)
113: break;
114: else if ((flag & T_CON) && n++ == 0)
115: break;
116: /* else fall through... */
117: default:
118: return tp;
119: }
120: }
121: }
122:
123: /*
124: * Return true if xp represents a dword register other than ESP.
125: */
126: isreg(xp) register TREE *xp;
127: {
128: register REGNAME r;
129:
130: if ((xp->t_flag&T_REG) == 0)
131: return 0;
132: while (xp->t_op == LEAF)
133: xp = xp->t_lp;
134: r = xp->t_reg;
135: return (r==EAX || r==EBX || r==ECX || r==EDX
136: || r==ESI || r==EDI || r==EBP);
137: }
138:
139: /* end of n1/i386/amd.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.