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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.2/] [sim/] [mips/] [vr.igen] - Blame information for rev 438

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

Line No. Rev Author Line
1 330 jeremybenn
// -*- C -*-
2
//
3
// NEC specific instructions
4
//
5
 
6
:%s::::MFHI:int hi
7
{
8
  return hi ? "hi" : "";
9
}
10
 
11
:%s::::SAT:int s
12
{
13
  return s ? "s" : "";
14
}
15
 
16
:%s::::UNS:int u
17
{
18
  return u ? "u" : "";
19
}
20
 
21
// Simulate the various kinds of multiply and multiply-accumulate instructions.
22
// Perform an operation of the form:
23
//
24
//      LHS (+/-) GPR[RS] * GPR[RT]
25
//
26
// and store it in the 64-bit accumulator.  Optionally copy either LO or
27
// HI into a general purpose register.
28
//
29
// - RD is the destination register of the LO or HI move
30
// - RS are RT are the multiplication source registers
31
// - ACCUMULATE_P is true if LHS should be the value of the 64-bit accumulator,
32
//     false if it should be 0.
33
// - STORE_HI_P is true if HI should be stored in RD, false if LO should be.
34
// - UNSIGNED_P is true if the operation should be unsigned.
35
// - SATURATE_P is true if the result should be saturated to a 32-bit value.
36
// - SUBTRACT_P is true if the right hand side should be subtraced from LHS,
37
//     false if it should be added.
38
// - SHORT_P is true if RS and RT must be 16-bit numbers.
39
// - DOUBLE_P is true if the 64-bit accumulator is in LO, false it is a
40
//     concatenation of the low 32 bits of HI and LO.
41
:function:::void:do_vr_mul_op:int rd, int rs, int rt, int accumulate_p, int store_hi_p, int unsigned_p, int saturate_p, int subtract_p, int short_p, int double_p
42
{
43
  unsigned64 lhs, x, y, xcut, ycut, product, result;
44
 
45
  check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
46
 
47
  lhs = (!accumulate_p ? 0 : double_p ? LO : U8_4 (HI, LO));
48
  x = GPR[rs];
49
  y = GPR[rt];
50
 
51
  /* Work out the canonical form of X and Y from their significant bits.  */
52
  if (!short_p)
53
    {
54
      /* Normal sign-extension rule for 32-bit operands.  */
55
      xcut = EXTEND32 (x);
56
      ycut = EXTEND32 (y);
57
    }
58
  else if (unsigned_p)
59
    {
60
      /* Operands must be zero-extended 16-bit numbers.  */
61
      xcut = x & 0xffff;
62
      ycut = y & 0xffff;
63
    }
64
  else
65
    {
66
      /* Likewise but sign-extended.  */
67
      xcut = EXTEND16 (x);
68
      ycut = EXTEND16 (y);
69
    }
70
  if (x != xcut || y != ycut)
71
    sim_engine_abort (SD, CPU, CIA,
72
                      "invalid multiplication operand at 0x%08lx\n",
73
                      (long) CIA);
74
 
75
  TRACE_ALU_INPUT2 (x, y);
76
  product = (unsigned_p
77
             ? V8_4 (x, 1) * V8_4 (y, 1)
78
             : EXTEND32 (x) * EXTEND32 (y));
79
  result = (subtract_p ? lhs - product : lhs + product);
80
  if (saturate_p)
81
    {
82
      /* Saturate the result to 32 bits.  An unsigned, unsaturated
83
         result is zero-extended to 64 bits, but unsigned overflow
84
         causes all 64 bits to be set.  */
85
      if (!unsigned_p && (unsigned64) EXTEND32 (result) != result)
86
        result = ((signed64) result < 0 ? -0x7fffffff - 1 : 0x7fffffff);
87
      else if (unsigned_p && (result >> 32) != 0)
88
        result = (unsigned64) 0 - 1;
89
    }
90
  TRACE_ALU_RESULT (result);
91
 
92
  if (double_p)
93
    LO = result;
94
  else
95
    {
96
      LO = EXTEND32 (result);
97
      HI = EXTEND32 (VH4_8 (result));
98
    }
99
  if (rd != 0)
100
    GPR[rd] = store_hi_p ? HI : LO;
101
}
102
 
103
// VR4100 instructions.
104
 
105
000000,5.RS,5.RT,00000,00000,101000::32::MADD16
106
"madd16 r, r"
107
*vr4100:
108
{
109
  do_vr_mul_op (SD_, 0, RS, RT,
110
                1 /* accumulate */,
111
 
112
 
113
 
114
 
115
                1 /* short */,
116
 
117
}
118
 
119
000000,5.RS,5.RT,00000,00000,101001::64::DMADD16
120
"dmadd16 r, r"
121
*vr4100:
122
{
123
  do_vr_mul_op (SD_, 0, RS, RT,
124
                1 /* accumulate */,
125
 
126
 
127
 
128
 
129
                1 /* short */,
130
                1 /* double */);
131
}
132
 
133
 
134
 
135
// VR4120 and VR4130 instructions.
136
 
137
000000,5.RS,5.RT,5.RD,1.SAT,1.MFHI,00,1.UNS,101001::64::DMACC
138
"dmacc%s%s%s r, r, r"
139
*vr4120:
140
{
141
  do_vr_mul_op (SD_, RD, RS, RT,
142
                1 /* accumulate */,
143
                MFHI, UNS, SAT,
144
 
145
                SAT /* short */,
146
                1 /* double */);
147
}
148
 
149
000000,5.RS,5.RT,5.RD,1.SAT,1.MFHI,00,1.UNS,101000::32::MACC_4120
150
"macc%s%s%s r, r, r"
151
*vr4120:
152
{
153
  do_vr_mul_op (SD_, RD, RS, RT,
154
                1 /* accumulate */,
155
                MFHI, UNS, SAT,
156
 
157
                SAT /* short */,
158
 
159
}
160
 
161
 
162
// VR5400 and VR5500 instructions.
163
 
164
000000,5.RS,5.RT,5.RD,0,1.MFHI,001,01100,1.UNS::32::MUL
165
"mul%s%s r, r, r"
166
*vr5400:
167
*vr5500:
168
{
169
  do_vr_mul_op (SD_, RD, RS, RT,
170
 
171
                MFHI, UNS,
172
 
173
 
174
 
175
 
176
}
177
 
178
000000,5.RS,5.RT,5.RD,0,1.MFHI,011,01100,1.UNS::32::MULS
179
"muls%s%s r, r, r"
180
*vr5400:
181
*vr5500:
182
{
183
  do_vr_mul_op (SD_, RD, RS, RT,
184
 
185
                MFHI, UNS,
186
 
187
                1 /* subtract */,
188
 
189
 
190
}
191
 
192
000000,5.RS,5.RT,5.RD,0,1.MFHI,101,01100,1.UNS::32::MACC_5xxx
193
"macc%s%s r, r, r"
194
*vr5400:
195
*vr5500:
196
{
197
  do_vr_mul_op (SD_, RD, RS, RT,
198
                1 /* accumulate */,
199
                MFHI, UNS,
200
 
201
 
202
 
203
 
204
}
205
 
206
000000,5.RS,5.RT,5.RD,0,1.MFHI,111,01100,1.UNS::32::MSAC
207
"msac%s%s r, r, r"
208
*vr5400:
209
*vr5500:
210
{
211
  do_vr_mul_op (SD_, RD, RS, RT,
212
                1 /* accumulate */,
213
                MFHI, UNS,
214
 
215
                1 /* subtract */,
216
 
217
 
218
}
219
 
220
 
221
010011,5.BASE,5.INDEX,5.0,5.FD,000101:COP1X:64::LUXC1
222
"luxc1 f, r(r)"
223
*vr5500:
224
{
225
  check_fpu (SD_);
226
  COP_LD (1, FD, do_load (SD_, AccessLength_DOUBLEWORD,
227
                          (GPR[BASE] + GPR[INDEX]) & ~MASK64 (2, 0), 0));
228
}
229
 
230
010011,5.BASE,5.INDEX,5.FS,00000,001101:COP1X:64::SUXC1
231
"suxc1 f, r(r)"
232
*vr5500:
233
{
234
  check_fpu (SD_);
235
  do_store (SD_, AccessLength_DOUBLEWORD,
236
            (GPR[BASE] + GPR[INDEX]) & ~MASK64 (2, 0), 0,
237
            COP_SD (1, FS));
238
}
239
 
240
010000,1,19.*,100000:COP0:32::WAIT
241
"wait"
242
*vr5500:
243
 
244
011100,00000,5.RT,5.DR,00000,111101:SPECIAL:64::MFDR
245
"mfdr r, r"
246
*vr5400:
247
*vr5500:
248
 
249
011100,00100,5.RT,5.DR,00000,111101:SPECIAL:64::MTDR
250
"mtdr r, r"
251
*vr5400:
252
*vr5500:
253
 
254
011100,00000,00000,00000,00000,111110:SPECIAL:64::DRET
255
"dret"
256
*vr5400:
257
*vr5500:

powered by: WebSVN 2.1.0

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