|
|
1.1 root 1: /* Subroutines for insn-output.c for Vax.
2: Copyright (C) 1987 Free Software Foundation, Inc.
3:
4: This file is part of GNU CC.
5:
6: GNU CC is free software; you can redistribute it and/or modify
7: it under the terms of the GNU General Public License as published by
8: the Free Software Foundation; either version 2, or (at your option)
9: any later version.
10:
11: GNU CC is distributed in the hope that it will be useful,
12: but WITHOUT ANY WARRANTY; without even the implied warranty of
13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: GNU General Public License for more details.
15:
16: You should have received a copy of the GNU General Public License
17: along with GNU CC; see the file COPYING. If not, write to
18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19:
20: #include <stdio.h>
21: #include "config.h"
22: #include "rtl.h"
23: #include "regs.h"
24: #include "hard-reg-set.h"
25: #include "real.h"
26: #include "insn-config.h"
27: #include "conditions.h"
28: #include "insn-flags.h"
29: #include "output.h"
30: #include "insn-attr.h"
31:
32: /* Return 1 if the operand is a REG, a SUBREG, or a MEM that is does not
33: have an index. This is used when we are using an operand in a different
34: mode than the hardware expects. See jlbc/jlbs.
35:
36: This is nonimmedate_operand with a restriction on the type of MEM. */
37:
38: int
39: reg_or_nxmem_operand (op, mode)
40: rtx op;
41: enum machine_mode mode;
42: {
43: if (! nonimmediate_operand (op, mode))
44: return 0;
45:
46: if (GET_CODE (op) != MEM)
47: return 1;
48:
49: GO_IF_NONINDEXED_ADDRESS (XEXP (op, 0), nonidx);
50:
51: return 0;
52:
53: nonidx:
54: return 1;
55: }
56:
57: void
58: split_quadword_operands (operands, low, n)
59: rtx *operands, *low;
60: int n;
61: {
62: int i;
63: /* Split operands. */
64:
65: low[0] = low[1] = low[2] = 0;
66: for (i = 0; i < 3; i++)
67: {
68: if (low[i])
69: /* it's already been figured out */;
70: else if (GET_CODE (operands[i]) == MEM
71: && (GET_CODE (XEXP (operands[i], 0)) == POST_INC))
72: {
73: rtx addr = XEXP (operands[i], 0);
74: operands[i] = low[i] = gen_rtx (MEM, SImode, addr);
75: if (which_alternative == 0 && i == 0)
76: {
77: addr = XEXP (operands[i], 0);
78: operands[i+1] = low[i+1] = gen_rtx (MEM, SImode, addr);
79: }
80: }
81: else
82: {
83: low[i] = operand_subword (operands[i], 0, 0, DImode);
84: operands[i] = operand_subword (operands[i], 1, 0, DImode);
85: }
86: }
87: }
88:
89: print_operand_address (file, addr)
90: FILE *file;
91: register rtx addr;
92: {
93: register rtx reg1, reg2, breg, ireg;
94: rtx offset;
95:
96: retry:
97: switch (GET_CODE (addr))
98: {
99: case MEM:
100: fprintf (file, "*");
101: addr = XEXP (addr, 0);
102: goto retry;
103:
104: case REG:
105: fprintf (file, "(%s)", reg_names[REGNO (addr)]);
106: break;
107:
108: case PRE_DEC:
109: fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
110: break;
111:
112: case POST_INC:
113: fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
114: break;
115:
116: case PLUS:
117: /* There can be either two or three things added here. One must be a
118: REG. One can be either a REG or a MULT of a REG and an appropriate
119: constant, and the third can only be a constant or a MEM.
120:
121: We get these two or three things and put the constant or MEM in
122: OFFSET, the MULT or REG in IREG, and the REG in BREG. If we have
123: a register and can't tell yet if it is a base or index register,
124: put it into REG1. */
125:
126: reg1 = 0; ireg = 0; breg = 0; offset = 0;
127:
128: if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
129: || GET_CODE (XEXP (addr, 0)) == MEM)
130: {
131: offset = XEXP (addr, 0);
132: addr = XEXP (addr, 1);
133: }
134: else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
135: || GET_CODE (XEXP (addr, 1)) == MEM)
136: {
137: offset = XEXP (addr, 1);
138: addr = XEXP (addr, 0);
139: }
140: else if (GET_CODE (XEXP (addr, 1)) == MULT)
141: {
142: ireg = XEXP (addr, 1);
143: addr = XEXP (addr, 0);
144: }
145: else if (GET_CODE (XEXP (addr, 0)) == MULT)
146: {
147: ireg = XEXP (addr, 0);
148: addr = XEXP (addr, 1);
149: }
150: else if (GET_CODE (XEXP (addr, 1)) == REG)
151: {
152: reg1 = XEXP (addr, 1);
153: addr = XEXP (addr, 0);
154: }
155: else
156: abort ();
157:
158: if (GET_CODE (addr) == REG)
159: {
160: if (reg1)
161: ireg = addr;
162: else
163: reg1 = addr;
164: }
165: else if (GET_CODE (addr) == MULT)
166: ireg = addr;
167: else if (GET_CODE (addr) == PLUS)
168: {
169: if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
170: || GET_CODE (XEXP (addr, 0)) == MEM)
171: {
172: if (offset)
173: {
174: if (GET_CODE (offset) == CONST_INT)
175: offset = plus_constant (XEXP (addr, 0), INTVAL (offset));
176: else if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
177: offset = plus_constant (offset, INTVAL (XEXP (addr, 0)));
178: else
179: abort ();
180: }
181: offset = XEXP (addr, 0);
182: }
183: else if (GET_CODE (XEXP (addr, 0)) == REG)
184: {
185: if (reg1)
186: ireg = reg1, breg = XEXP (addr, 0), reg1 = 0;
187: else
188: reg1 = XEXP (addr, 0);
189: }
190: else if (GET_CODE (XEXP (addr, 0)) == MULT)
191: {
192: if (ireg)
193: abort ();
194: ireg = XEXP (addr, 0);
195: }
196: else
197: abort ();
198:
199: if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
200: || GET_CODE (XEXP (addr, 1)) == MEM)
201: {
202: if (offset)
203: {
204: if (GET_CODE (offset) == CONST_INT)
205: offset = plus_constant (XEXP (addr, 1), INTVAL (offset));
206: else if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
207: offset = plus_constant (offset, INTVAL (XEXP (addr, 1)));
208: else
209: abort ();
210: }
211: offset = XEXP (addr, 1);
212: }
213: else if (GET_CODE (XEXP (addr, 1)) == REG)
214: {
215: if (reg1)
216: ireg = reg1, breg = XEXP (addr, 1), reg1 = 0;
217: else
218: reg1 = XEXP (addr, 1);
219: }
220: else if (GET_CODE (XEXP (addr, 1)) == MULT)
221: {
222: if (ireg)
223: abort ();
224: ireg = XEXP (addr, 1);
225: }
226: else
227: abort ();
228: }
229: else
230: abort ();
231:
232: /* If REG1 is non-zero, figure out if it is a base or index register. */
233: if (reg1)
234: {
235: if (breg != 0 || (offset && GET_CODE (offset) == MEM))
236: {
237: if (ireg)
238: abort ();
239: ireg = reg1;
240: }
241: else
242: breg = reg1;
243: }
244:
245: if (offset != 0)
246: output_address (offset);
247:
248: if (breg != 0)
249: fprintf (file, "(%s)", reg_names[REGNO (breg)]);
250:
251: if (ireg != 0)
252: {
253: if (GET_CODE (ireg) == MULT)
254: ireg = XEXP (ireg, 0);
255: if (GET_CODE (ireg) != REG)
256: abort ();
257: fprintf (file, "[%s]", reg_names[REGNO (ireg)]);
258: }
259: break;
260:
261: default:
262: output_addr_const (file, addr);
263: }
264: }
265:
266: char *
267: rev_cond_name (op)
268: rtx op;
269: {
270: switch (GET_CODE (op))
271: {
272: case EQ:
273: return "neq";
274: case NE:
275: return "eql";
276: case LT:
277: return "geq";
278: case LE:
279: return "gtr";
280: case GT:
281: return "leq";
282: case GE:
283: return "lss";
284: case LTU:
285: return "gequ";
286: case LEU:
287: return "gtru";
288: case GTU:
289: return "lequ";
290: case GEU:
291: return "lssu";
292:
293: default:
294: abort ();
295: }
296: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.