OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [sim/] [ppc/] [idecode_expression.h] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*  This file is part of the program psim.
2
 
3
    Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
4
 
5
    This program is free software; you can redistribute it and/or modify
6
    it under the terms of the GNU General Public License as published by
7
    the Free Software Foundation; either version 2 of the License, or
8
    (at your option) any later version.
9
 
10
    This program is distributed in the hope that it will be useful,
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
    GNU General Public License for more details.
14
 
15
    You should have received a copy of the GNU General Public License
16
    along with this program; if not, write to the Free Software
17
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
 
19
    */
20
 
21
 
22
/* 32bit target expressions:
23
 
24
   Each calculation is performed three times using each of the
25
   signed64, unsigned64 and long integer types.  The macro ALU_END
26
   (in _ALU_RESULT_VAL) then selects which of the three alternative
27
   results will be used in the final assignment of the target
28
   register.  As this selection is determined at compile time by
29
   fields in the instruction (OE, EA, Rc) the compiler has sufficient
30
   information to firstly simplify the selection code into a single
31
   case and then back anotate the equations and hence eliminate any
32
   resulting dead code.  That dead code being the calculations that,
33
   as it turned out were not in the end needed.
34
 
35
   64bit arrithemetic is used firstly because it allows the use of
36
   gcc's efficient long long operators (typically efficiently output
37
   inline) and secondly because the resultant answer will contain in
38
   the low 32bits the answer while in the high 32bits is either carry
39
   or status information. */
40
 
41
/* 64bit target expressions:
42
 
43
   Unfortunatly 128bit arrithemetic isn't that common.  Consequently
44
   the 32/64 bit trick can not be used.  Instead all calculations are
45
   required to retain carry/overflow information in separate
46
   variables.  Even with this restriction it is still possible for the
47
   trick of letting the compiler discard the calculation of unneeded
48
   values */
49
 
50
 
51
/* Macro's to type cast 32bit constants to 64bits */
52
#define SIGNED64(val)   ((signed64)(signed32)(val))
53
#define UNSIGNED64(val) ((unsigned64)(unsigned32)(val))
54
 
55
 
56
/* Start a section of ALU code */
57
 
58
#define ALU_BEGIN(val) \
59
{ \
60
  natural_word alu_val; \
61
  unsigned64 alu_carry_val; \
62
  signed64 alu_overflow_val; \
63
  ALU_SET(val)
64
 
65
 
66
/* assign the result to the target register */
67
 
68
#define ALU_END(TARG,CA,OE,Rc) \
69
{ /* select the result to use */ \
70
  signed_word const alu_result = _ALU_RESULT_VAL(CA,OE,Rc); \
71
  /* determine the overflow bit if needed */ \
72
  if (OE) { \
73
    if ((((unsigned64)(alu_overflow_val & BIT64(0))) \
74
         >> 32) \
75
        == (alu_overflow_val & BIT64(32))) \
76
      XER &= (~xer_overflow); \
77
    else \
78
      XER |= (xer_summary_overflow | xer_overflow); \
79
  } \
80
  /* Update the carry bit if needed */ \
81
  if (CA) { \
82
    XER = ((XER & ~xer_carry) \
83
           | SHUFFLED32((alu_carry_val >> 32), 31, xer_carry_bit)); \
84
    /* if (alu_carry_val & BIT64(31)) \
85
         XER |= (xer_carry); \
86
       else \
87
         XER &= (~xer_carry); */ \
88
  } \
89
  TRACE(trace_alu, (" Result = %ld (0x%lx), XER = %ld\n", \
90
                    (long)alu_result, (long)alu_result, (long)XER)); \
91
  /* Update the Result Conditions if needed */ \
92
  CR0_COMPARE(alu_result, 0, Rc); \
93
  /* assign targ same */ \
94
  TARG = alu_result; \
95
}}
96
 
97
/* select the result from the different options */
98
 
99
#define _ALU_RESULT_VAL(CA,OE,Rc) (WITH_TARGET_WORD_BITSIZE == 64 \
100
                                   ? alu_val \
101
                                   : (OE \
102
                                      ? alu_overflow_val \
103
                                      : (CA \
104
                                         ? alu_carry_val \
105
                                         : alu_val)))
106
 
107
 
108
/* More basic alu operations */
109
#if (WITH_TARGET_WORD_BITSIZE == 64)
110
#define ALU_SET(val) \
111
do { \
112
  alu_val = val; \
113
  alu_carry_val = ((unsigned64)alu_val) >> 32; \
114
  alu_overflow_val = ((signed64)alu_val) >> 32; \
115
} while (0)
116
#endif
117
#if (WITH_TARGET_WORD_BITSIZE == 32)
118
#define ALU_SET(val) \
119
do { \
120
  alu_val = val; \
121
  alu_carry_val = (unsigned32)(alu_val); \
122
  alu_overflow_val = (signed32)(alu_val); \
123
} while (0)
124
#endif
125
 
126
#if (WITH_TARGET_WORD_BITSIZE == 64)
127
#define ALU_ADD(val) \
128
do { \
129
  unsigned64 alu_lo = (UNSIGNED64(alu_val) \
130
                       + UNSIGNED64(val)); \
131
  signed alu_carry = ((alu_lo & BIT(31)) != 0); \
132
  alu_carry_val = (alu_carry_val \
133
                   + UNSIGNED64(EXTRACTED(val, 0, 31)) \
134
                   + alu_carry); \
135
  alu_overflow_val = (alu_overflow_val \
136
                      + SIGNED64(EXTRACTED(val, 0, 31)) \
137
                      + alu_carry); \
138
  alu_val = alu_val + val; \
139
} while (0)
140
#endif
141
#if (WITH_TARGET_WORD_BITSIZE == 32)
142
#define ALU_ADD(val) \
143
do { \
144
  alu_val += val; \
145
  alu_carry_val += (unsigned32)(val); \
146
  alu_overflow_val += (signed32)(val); \
147
} while (0)
148
#endif
149
 
150
 
151
#if (WITH_TARGET_WORD_BITSIZE == 64)
152
#define ALU_ADD_CA \
153
do { \
154
  signed carry = MASKED32(XER, xer_carry_bit, xer_carry_bit) != 0; \
155
  ALU_ADD(carry); \
156
} while (0)
157
#endif
158
#if (WITH_TARGET_WORD_BITSIZE == 32)
159
#define ALU_ADD_CA \
160
do { \
161
  signed carry = MASKED32(XER, xer_carry_bit, xer_carry_bit) != 0; \
162
  ALU_ADD(carry); \
163
} while (0)
164
#endif
165
 
166
 
167
#if 0
168
#if (WITH_TARGET_WORD_BITSIZE == 64)
169
#endif
170
#if (WITH_TARGET_WORD_BITSIZE == 32)
171
#define ALU_SUB(val) \
172
do { \
173
  alu_val -= val; \
174
  alu_carry_val -= (unsigned32)(val); \
175
  alu_overflow_val -= (signed32)(val); \
176
} while (0)
177
#endif
178
#endif
179
 
180
#if (WITH_TARGET_WORD_BITSIZE == 64)
181
#endif
182
#if (WITH_TARGET_WORD_BITSIZE == 32)
183
#define ALU_OR(val) \
184
do { \
185
  alu_val |= val; \
186
  alu_carry_val = (unsigned32)(alu_val); \
187
  alu_overflow_val = (signed32)(alu_val); \
188
} while (0)
189
#endif
190
 
191
 
192
#if (WITH_TARGET_WORD_BITSIZE == 64)
193
#endif
194
#if (WITH_TARGET_WORD_BITSIZE == 32)
195
#define ALU_XOR(val) \
196
do { \
197
  alu_val ^= val; \
198
  alu_carry_val = (unsigned32)(alu_val); \
199
  alu_overflow_val = (signed32)(alu_val); \
200
} while (0)
201
#endif
202
 
203
 
204
#if 0
205
#if (WITH_TARGET_WORD_BITSIZE == 64)
206
#endif
207
#if (WITH_TARGET_WORD_BITSIZE == 32)
208
#define ALU_NEGATE \
209
do { \
210
  alu_val = -alu_val; \
211
  alu_carry_val = -alu_carry_val; \
212
  alu_overflow_val = -alu_overflow_val; \
213
} while(0)
214
#endif
215
#endif
216
 
217
 
218
#if (WITH_TARGET_WORD_BITSIZE == 64)
219
#endif
220
#if (WITH_TARGET_WORD_BITSIZE == 32)
221
#define ALU_AND(val) \
222
do { \
223
  alu_val &= val; \
224
  alu_carry_val = (unsigned32)(alu_val); \
225
  alu_overflow_val = (signed32)(alu_val); \
226
} while (0)
227
#endif
228
 
229
 
230
#if (WITH_TARGET_WORD_BITSIZE == 64)
231
#define ALU_NOT \
232
do { \
233
  signed64 new_alu_val = ~alu_val; \
234
  ALU_SET(new_alu_val); \
235
} while (0)
236
#endif
237
#if (WITH_TARGET_WORD_BITSIZE == 32)
238
#define ALU_NOT \
239
do { \
240
  signed new_alu_val = ~alu_val; \
241
  ALU_SET(new_alu_val); \
242
} while(0)
243
#endif
244
 
245
 
246
/* Macros for updating the condition register */
247
 
248
#define CR1_UPDATE(Rc) \
249
do { \
250
  if (Rc) { \
251
    CR_SET(1, EXTRACTED32(FPSCR, fpscr_fx_bit, fpscr_ox_bit)); \
252
  } \
253
} while (0)
254
 
255
 
256
#define _DO_CR_COMPARE(LHS, RHS) \
257
(((LHS) < (RHS)) \
258
 ? cr_i_negative \
259
 : (((LHS) > (RHS)) \
260
    ? cr_i_positive \
261
    : cr_i_zero))
262
 
263
#define CR_SET(REG, VAL) MBLIT32(CR, REG*4, REG*4+3, VAL)
264
#define CR_FIELD(REG) EXTRACTED32(CR, REG*4, REG*4+3)
265
#define CR_SET_XER_SO(REG, VAL) \
266
do { \
267
  creg new_bits = ((XER & xer_summary_overflow) \
268
                   ? (cr_i_summary_overflow | VAL) \
269
                   : VAL); \
270
  CR_SET(REG, new_bits); \
271
} while(0)
272
 
273
#define CR_COMPARE(REG, LHS, RHS) \
274
do { \
275
  creg new_bits = ((XER & xer_summary_overflow) \
276
                   ? (cr_i_summary_overflow | _DO_CR_COMPARE(LHS,RHS)) \
277
                   : _DO_CR_COMPARE(LHS,RHS)); \
278
  CR_SET(REG, new_bits); \
279
} while (0)
280
 
281
#define CR0_COMPARE(LHS, RHS, Rc) \
282
do { \
283
  if (Rc) { \
284
    CR_COMPARE(0, LHS, RHS); \
285
    TRACE(trace_alu, \
286
          ("CR=0x%08lx, LHS=%ld, RHS=%ld\n", \
287
           (unsigned long)CR, (long)LHS, (long)RHS)); \
288
  } \
289
} while (0)
290
 
291
 
292
 
293
/* Bring data in from the cold */
294
 
295
#define MEM(SIGN, EA, NR_BYTES) \
296
((SIGN##_##NR_BYTES) vm_data_map_read_##NR_BYTES(cpu_data_map(processor), EA, \
297
                                                 processor, cia)) \
298
 
299
#define STORE(EA, NR_BYTES, VAL) \
300
do { \
301
  vm_data_map_write_##NR_BYTES(cpu_data_map(processor), EA, VAL, \
302
                               processor, cia); \
303
} while (0)
304
 
305
 
306
 
307
/* some FPSCR update macros. */
308
 
309
#define FPSCR_BEGIN \
310
{ \
311
  fpscreg old_fpscr UNUSED = FPSCR
312
 
313
#define FPSCR_END(Rc) { \
314
  /* always update VX */ \
315
  if ((FPSCR & fpscr_vx_bits)) \
316
    FPSCR |= fpscr_vx; \
317
  else \
318
    FPSCR &= ~fpscr_vx; \
319
  /* always update FEX */ \
320
  if (((FPSCR & fpscr_vx) && (FPSCR & fpscr_ve)) \
321
      || ((FPSCR & fpscr_ox) && (FPSCR & fpscr_oe)) \
322
      || ((FPSCR & fpscr_ux) && (FPSCR & fpscr_ue)) \
323
      || ((FPSCR & fpscr_zx) && (FPSCR & fpscr_ze)) \
324
      || ((FPSCR & fpscr_xx) && (FPSCR & fpscr_xe))) \
325
    FPSCR |= fpscr_fex; \
326
  else \
327
    FPSCR &= ~fpscr_fex; \
328
  CR1_UPDATE(Rc); \
329
  /* interrupt enabled? */ \
330
  if ((MSR & (msr_floating_point_exception_mode_0 \
331
              | msr_floating_point_exception_mode_1)) \
332
      && (FPSCR & fpscr_fex)) \
333
    program_interrupt(processor, cia, \
334
                      floating_point_enabled_program_interrupt); \
335
}}
336
 
337
#define FPSCR_SET(REG, VAL) MBLIT32(FPSCR, REG*4, REG*4+3, VAL)
338
#define FPSCR_FIELD(REG) EXTRACTED32(FPSCR, REG*4, REG*4+3)
339
 
340
#define FPSCR_SET_FPCC(VAL) MBLIT32(FPSCR, fpscr_fpcc_bit, fpscr_fpcc_bit+3, VAL)
341
 
342
/* Handle various exceptions */
343
 
344
#define FPSCR_OR_VX(VAL) \
345
do { \
346
  /* NOTE: VAL != 0 */ \
347
  FPSCR |= (VAL); \
348
  FPSCR |= fpscr_fx; \
349
} while (0)
350
 
351
#define FPSCR_SET_OX(COND) \
352
do { \
353
  if (COND) { \
354
    FPSCR |= fpscr_ox; \
355
    FPSCR |= fpscr_fx; \
356
  } \
357
  else \
358
    FPSCR &= ~fpscr_ox; \
359
} while (0)
360
 
361
#define FPSCR_SET_UX(COND) \
362
do { \
363
  if (COND) { \
364
    FPSCR |= fpscr_ux; \
365
    FPSCR |= fpscr_fx; \
366
  } \
367
  else \
368
    FPSCR &= ~fpscr_ux; \
369
} while (0)
370
 
371
#define FPSCR_SET_ZX(COND) \
372
do { \
373
  if (COND) { \
374
    FPSCR |= fpscr_zx; \
375
    FPSCR |= fpscr_fx; \
376
  } \
377
  else \
378
    FPSCR &= ~fpscr_zx; \
379
} while (0)
380
 
381
#define FPSCR_SET_XX(COND) \
382
do { \
383
  if (COND) { \
384
    FPSCR |= fpscr_xx; \
385
    FPSCR |= fpscr_fx; \
386
  } \
387
} while (0)
388
 
389
/* Note: code using SET_FI must also explicitly call SET_XX */
390
 
391
#define FPSCR_SET_FR(COND) do { \
392
  if (COND) \
393
    FPSCR |= fpscr_fr; \
394
  else \
395
    FPSCR &= ~fpscr_fr; \
396
} while (0)
397
 
398
#define FPSCR_SET_FI(COND) \
399
do { \
400
  if (COND) { \
401
    FPSCR |= fpscr_fi; \
402
  } \
403
  else \
404
    FPSCR &= ~fpscr_fi; \
405
} while (0)
406
 
407
#define FPSCR_SET_FPRF(VAL) \
408
do { \
409
  FPSCR = (FPSCR & ~fpscr_fprf) | (VAL); \
410
} while (0)

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.