Revision cf495bcf target-sparc/translate.c

b/target-sparc/translate.c
34 34
   and the 'anull' bit in the branch instruction opcode is set. This is
35 35
   currently solved by doing a jump after the delay slot instruction.
36 36

  
37
   There is also one big (currently unsolved) bug in the branch code:
38
   If a delay slot modifies the condition codes then the new condition
39
   codes, instead of the old ones will be used.
40

  
41 37
   TODO-list:
42 38

  
39
   Register window overflow/underflow check
43 40
   FPU-Instructions
44 41
   Coprocessor-Instructions
45
   Fix above bug
46 42
   Check signedness issues
47 43
   Privileged instructions
48
   Register window overflow/underflow check
49 44
   Optimize synthetic instructions
50 45
   Optional alignment and privileged instruction check
51 46

  
......
65 60
#define DEBUG_DISAS
66 61

  
67 62
typedef struct DisasContext {
68
	uint8_t *pc;
69
	uint8_t *npc;
70
	void (*branch) (struct DisasContext *, uint32_t, uint32_t);
71
	unsigned int delay_slot:2;
72
	uint32_t insn;
73
	uint32_t target;
74
	int      is_br;
75
	struct TranslationBlock *tb;
63
    uint8_t *pc;		/* NULL means dynamic value */
64
    uint8_t *npc;		/* NULL means dynamic value */
65
    int is_br;
66
    struct TranslationBlock *tb;
76 67
} DisasContext;
77 68

  
78 69
static uint16_t *gen_opc_ptr;
......
84 75
#define DEF(s,n,copy_size) INDEX_op_ ## s,
85 76
#include "opc.h"
86 77
#undef DEF
87
	NB_OPS
78
    NB_OPS
88 79
};
89 80

  
90 81
#include "gen-op.h"
......
94 85

  
95 86
#define IS_IMM (insn & (1<<13))
96 87

  
97
static void disas_sparc_insn (DisasContext *dc);
88
static void disas_sparc_insn(DisasContext * dc);
98 89

  
99
typedef void (GenOpFunc)(void);
100
typedef void (GenOpFunc1)(long);
101
typedef void (GenOpFunc2)(long, long);
102
typedef void (GenOpFunc3)(long, long, long);
90
typedef void (GenOpFunc) (void);
91
typedef void (GenOpFunc1) (long);
92
typedef void (GenOpFunc2) (long, long);
93
typedef void (GenOpFunc3) (long, long, long);
103 94

  
104 95
static GenOpFunc *gen_op_movl_TN_reg[2][32] = {
105
	{
106
		gen_op_movl_g0_T0,
107
		gen_op_movl_g1_T0,
108
		gen_op_movl_g2_T0,
109
		gen_op_movl_g3_T0,
110
		gen_op_movl_g4_T0,
111
		gen_op_movl_g5_T0,
112
		gen_op_movl_g6_T0,
113
		gen_op_movl_g7_T0,
114
		gen_op_movl_o0_T0,
115
		gen_op_movl_o1_T0,
116
		gen_op_movl_o2_T0,
117
		gen_op_movl_o3_T0,
118
		gen_op_movl_o4_T0,
119
		gen_op_movl_o5_T0,
120
		gen_op_movl_o6_T0,
121
		gen_op_movl_o7_T0,
122
		gen_op_movl_l0_T0,
123
		gen_op_movl_l1_T0,
124
		gen_op_movl_l2_T0,
125
		gen_op_movl_l3_T0,
126
		gen_op_movl_l4_T0,
127
		gen_op_movl_l5_T0,
128
		gen_op_movl_l6_T0,
129
		gen_op_movl_l7_T0,
130
		gen_op_movl_i0_T0,
131
		gen_op_movl_i1_T0,
132
		gen_op_movl_i2_T0,
133
		gen_op_movl_i3_T0,
134
		gen_op_movl_i4_T0,
135
		gen_op_movl_i5_T0,
136
		gen_op_movl_i6_T0,
137
		gen_op_movl_i7_T0,
138
	},
139
	{
140
		gen_op_movl_g0_T1,
141
		gen_op_movl_g1_T1,
142
		gen_op_movl_g2_T1,
143
		gen_op_movl_g3_T1,
144
		gen_op_movl_g4_T1,
145
		gen_op_movl_g5_T1,
146
		gen_op_movl_g6_T1,
147
		gen_op_movl_g7_T1,
148
		gen_op_movl_o0_T1,
149
		gen_op_movl_o1_T1,
150
		gen_op_movl_o2_T1,
151
		gen_op_movl_o3_T1,
152
		gen_op_movl_o4_T1,
153
		gen_op_movl_o5_T1,
154
		gen_op_movl_o6_T1,
155
		gen_op_movl_o7_T1,
156
		gen_op_movl_l0_T1,
157
		gen_op_movl_l1_T1,
158
		gen_op_movl_l2_T1,
159
		gen_op_movl_l3_T1,
160
		gen_op_movl_l4_T1,
161
		gen_op_movl_l5_T1,
162
		gen_op_movl_l6_T1,
163
		gen_op_movl_l7_T1,
164
		gen_op_movl_i0_T1,
165
		gen_op_movl_i1_T1,
166
		gen_op_movl_i2_T1,
167
		gen_op_movl_i3_T1,
168
		gen_op_movl_i4_T1,
169
		gen_op_movl_i5_T1,
170
		gen_op_movl_i6_T1,
171
		gen_op_movl_i7_T1,
172
	}
96
    {
97
     gen_op_movl_g0_T0,
98
     gen_op_movl_g1_T0,
99
     gen_op_movl_g2_T0,
100
     gen_op_movl_g3_T0,
101
     gen_op_movl_g4_T0,
102
     gen_op_movl_g5_T0,
103
     gen_op_movl_g6_T0,
104
     gen_op_movl_g7_T0,
105
     gen_op_movl_o0_T0,
106
     gen_op_movl_o1_T0,
107
     gen_op_movl_o2_T0,
108
     gen_op_movl_o3_T0,
109
     gen_op_movl_o4_T0,
110
     gen_op_movl_o5_T0,
111
     gen_op_movl_o6_T0,
112
     gen_op_movl_o7_T0,
113
     gen_op_movl_l0_T0,
114
     gen_op_movl_l1_T0,
115
     gen_op_movl_l2_T0,
116
     gen_op_movl_l3_T0,
117
     gen_op_movl_l4_T0,
118
     gen_op_movl_l5_T0,
119
     gen_op_movl_l6_T0,
120
     gen_op_movl_l7_T0,
121
     gen_op_movl_i0_T0,
122
     gen_op_movl_i1_T0,
123
     gen_op_movl_i2_T0,
124
     gen_op_movl_i3_T0,
125
     gen_op_movl_i4_T0,
126
     gen_op_movl_i5_T0,
127
     gen_op_movl_i6_T0,
128
     gen_op_movl_i7_T0,
129
     },
130
    {
131
     gen_op_movl_g0_T1,
132
     gen_op_movl_g1_T1,
133
     gen_op_movl_g2_T1,
134
     gen_op_movl_g3_T1,
135
     gen_op_movl_g4_T1,
136
     gen_op_movl_g5_T1,
137
     gen_op_movl_g6_T1,
138
     gen_op_movl_g7_T1,
139
     gen_op_movl_o0_T1,
140
     gen_op_movl_o1_T1,
141
     gen_op_movl_o2_T1,
142
     gen_op_movl_o3_T1,
143
     gen_op_movl_o4_T1,
144
     gen_op_movl_o5_T1,
145
     gen_op_movl_o6_T1,
146
     gen_op_movl_o7_T1,
147
     gen_op_movl_l0_T1,
148
     gen_op_movl_l1_T1,
149
     gen_op_movl_l2_T1,
150
     gen_op_movl_l3_T1,
151
     gen_op_movl_l4_T1,
152
     gen_op_movl_l5_T1,
153
     gen_op_movl_l6_T1,
154
     gen_op_movl_l7_T1,
155
     gen_op_movl_i0_T1,
156
     gen_op_movl_i1_T1,
157
     gen_op_movl_i2_T1,
158
     gen_op_movl_i3_T1,
159
     gen_op_movl_i4_T1,
160
     gen_op_movl_i5_T1,
161
     gen_op_movl_i6_T1,
162
     gen_op_movl_i7_T1,
163
     }
173 164
};
174 165

  
175 166
static GenOpFunc *gen_op_movl_reg_TN[3][32] = {
176
	{
177
		gen_op_movl_T0_g0,
178
		gen_op_movl_T0_g1,
179
		gen_op_movl_T0_g2,
180
		gen_op_movl_T0_g3,
181
		gen_op_movl_T0_g4,
182
		gen_op_movl_T0_g5,
183
		gen_op_movl_T0_g6,
184
		gen_op_movl_T0_g7,
185
		gen_op_movl_T0_o0,
186
		gen_op_movl_T0_o1,
187
		gen_op_movl_T0_o2,
188
		gen_op_movl_T0_o3,
189
		gen_op_movl_T0_o4,
190
		gen_op_movl_T0_o5,
191
		gen_op_movl_T0_o6,
192
		gen_op_movl_T0_o7,
193
		gen_op_movl_T0_l0,
194
		gen_op_movl_T0_l1,
195
		gen_op_movl_T0_l2,
196
		gen_op_movl_T0_l3,
197
		gen_op_movl_T0_l4,
198
		gen_op_movl_T0_l5,
199
		gen_op_movl_T0_l6,
200
		gen_op_movl_T0_l7,
201
		gen_op_movl_T0_i0,
202
		gen_op_movl_T0_i1,
203
		gen_op_movl_T0_i2,
204
		gen_op_movl_T0_i3,
205
		gen_op_movl_T0_i4,
206
		gen_op_movl_T0_i5,
207
		gen_op_movl_T0_i6,
208
		gen_op_movl_T0_i7,
209
	},
210
	{
211
		gen_op_movl_T1_g0,
212
		gen_op_movl_T1_g1,
213
		gen_op_movl_T1_g2,
214
		gen_op_movl_T1_g3,
215
		gen_op_movl_T1_g4,
216
		gen_op_movl_T1_g5,
217
		gen_op_movl_T1_g6,
218
		gen_op_movl_T1_g7,
219
		gen_op_movl_T1_o0,
220
		gen_op_movl_T1_o1,
221
		gen_op_movl_T1_o2,
222
		gen_op_movl_T1_o3,
223
		gen_op_movl_T1_o4,
224
		gen_op_movl_T1_o5,
225
		gen_op_movl_T1_o6,
226
		gen_op_movl_T1_o7,
227
		gen_op_movl_T1_l0,
228
		gen_op_movl_T1_l1,
229
		gen_op_movl_T1_l2,
230
		gen_op_movl_T1_l3,
231
		gen_op_movl_T1_l4,
232
		gen_op_movl_T1_l5,
233
		gen_op_movl_T1_l6,
234
		gen_op_movl_T1_l7,
235
		gen_op_movl_T1_i0,
236
		gen_op_movl_T1_i1,
237
		gen_op_movl_T1_i2,
238
		gen_op_movl_T1_i3,
239
		gen_op_movl_T1_i4,
240
		gen_op_movl_T1_i5,
241
		gen_op_movl_T1_i6,
242
		gen_op_movl_T1_i7,
243
	},
244
	{
245
		gen_op_movl_T2_g0,
246
		gen_op_movl_T2_g1,
247
		gen_op_movl_T2_g2,
248
		gen_op_movl_T2_g3,
249
		gen_op_movl_T2_g4,
250
		gen_op_movl_T2_g5,
251
		gen_op_movl_T2_g6,
252
		gen_op_movl_T2_g7,
253
		gen_op_movl_T2_o0,
254
		gen_op_movl_T2_o1,
255
		gen_op_movl_T2_o2,
256
		gen_op_movl_T2_o3,
257
		gen_op_movl_T2_o4,
258
		gen_op_movl_T2_o5,
259
		gen_op_movl_T2_o6,
260
		gen_op_movl_T2_o7,
261
		gen_op_movl_T2_l0,
262
		gen_op_movl_T2_l1,
263
		gen_op_movl_T2_l2,
264
		gen_op_movl_T2_l3,
265
		gen_op_movl_T2_l4,
266
		gen_op_movl_T2_l5,
267
		gen_op_movl_T2_l6,
268
		gen_op_movl_T2_l7,
269
		gen_op_movl_T2_i0,
270
		gen_op_movl_T2_i1,
271
		gen_op_movl_T2_i2,
272
		gen_op_movl_T2_i3,
273
		gen_op_movl_T2_i4,
274
		gen_op_movl_T2_i5,
275
		gen_op_movl_T2_i6,
276
		gen_op_movl_T2_i7,
277
	}
167
    {
168
     gen_op_movl_T0_g0,
169
     gen_op_movl_T0_g1,
170
     gen_op_movl_T0_g2,
171
     gen_op_movl_T0_g3,
172
     gen_op_movl_T0_g4,
173
     gen_op_movl_T0_g5,
174
     gen_op_movl_T0_g6,
175
     gen_op_movl_T0_g7,
176
     gen_op_movl_T0_o0,
177
     gen_op_movl_T0_o1,
178
     gen_op_movl_T0_o2,
179
     gen_op_movl_T0_o3,
180
     gen_op_movl_T0_o4,
181
     gen_op_movl_T0_o5,
182
     gen_op_movl_T0_o6,
183
     gen_op_movl_T0_o7,
184
     gen_op_movl_T0_l0,
185
     gen_op_movl_T0_l1,
186
     gen_op_movl_T0_l2,
187
     gen_op_movl_T0_l3,
188
     gen_op_movl_T0_l4,
189
     gen_op_movl_T0_l5,
190
     gen_op_movl_T0_l6,
191
     gen_op_movl_T0_l7,
192
     gen_op_movl_T0_i0,
193
     gen_op_movl_T0_i1,
194
     gen_op_movl_T0_i2,
195
     gen_op_movl_T0_i3,
196
     gen_op_movl_T0_i4,
197
     gen_op_movl_T0_i5,
198
     gen_op_movl_T0_i6,
199
     gen_op_movl_T0_i7,
200
     },
201
    {
202
     gen_op_movl_T1_g0,
203
     gen_op_movl_T1_g1,
204
     gen_op_movl_T1_g2,
205
     gen_op_movl_T1_g3,
206
     gen_op_movl_T1_g4,
207
     gen_op_movl_T1_g5,
208
     gen_op_movl_T1_g6,
209
     gen_op_movl_T1_g7,
210
     gen_op_movl_T1_o0,
211
     gen_op_movl_T1_o1,
212
     gen_op_movl_T1_o2,
213
     gen_op_movl_T1_o3,
214
     gen_op_movl_T1_o4,
215
     gen_op_movl_T1_o5,
216
     gen_op_movl_T1_o6,
217
     gen_op_movl_T1_o7,
218
     gen_op_movl_T1_l0,
219
     gen_op_movl_T1_l1,
220
     gen_op_movl_T1_l2,
221
     gen_op_movl_T1_l3,
222
     gen_op_movl_T1_l4,
223
     gen_op_movl_T1_l5,
224
     gen_op_movl_T1_l6,
225
     gen_op_movl_T1_l7,
226
     gen_op_movl_T1_i0,
227
     gen_op_movl_T1_i1,
228
     gen_op_movl_T1_i2,
229
     gen_op_movl_T1_i3,
230
     gen_op_movl_T1_i4,
231
     gen_op_movl_T1_i5,
232
     gen_op_movl_T1_i6,
233
     gen_op_movl_T1_i7,
234
     },
235
    {
236
     gen_op_movl_T2_g0,
237
     gen_op_movl_T2_g1,
238
     gen_op_movl_T2_g2,
239
     gen_op_movl_T2_g3,
240
     gen_op_movl_T2_g4,
241
     gen_op_movl_T2_g5,
242
     gen_op_movl_T2_g6,
243
     gen_op_movl_T2_g7,
244
     gen_op_movl_T2_o0,
245
     gen_op_movl_T2_o1,
246
     gen_op_movl_T2_o2,
247
     gen_op_movl_T2_o3,
248
     gen_op_movl_T2_o4,
249
     gen_op_movl_T2_o5,
250
     gen_op_movl_T2_o6,
251
     gen_op_movl_T2_o7,
252
     gen_op_movl_T2_l0,
253
     gen_op_movl_T2_l1,
254
     gen_op_movl_T2_l2,
255
     gen_op_movl_T2_l3,
256
     gen_op_movl_T2_l4,
257
     gen_op_movl_T2_l5,
258
     gen_op_movl_T2_l6,
259
     gen_op_movl_T2_l7,
260
     gen_op_movl_T2_i0,
261
     gen_op_movl_T2_i1,
262
     gen_op_movl_T2_i2,
263
     gen_op_movl_T2_i3,
264
     gen_op_movl_T2_i4,
265
     gen_op_movl_T2_i5,
266
     gen_op_movl_T2_i6,
267
     gen_op_movl_T2_i7,
268
     }
278 269
};
279 270

  
280 271
static GenOpFunc1 *gen_op_movl_TN_im[3] = {
281
	gen_op_movl_T0_im,
282
	gen_op_movl_T1_im,
283
	gen_op_movl_T2_im
272
    gen_op_movl_T0_im,
273
    gen_op_movl_T1_im,
274
    gen_op_movl_T2_im
284 275
};
285 276

  
286
static inline void gen_movl_imm_TN (int reg, int imm)
277
static inline void gen_movl_imm_TN(int reg, int imm)
287 278
{
288
	gen_op_movl_TN_im[reg](imm);
279
    gen_op_movl_TN_im[reg] (imm);
289 280
}
290 281

  
291
static inline void gen_movl_imm_T1 (int val)
282
static inline void gen_movl_imm_T1(int val)
292 283
{
293
	gen_movl_imm_TN (1, val);
284
    gen_movl_imm_TN(1, val);
294 285
}
295 286

  
296
static inline void gen_movl_imm_T0 (int val)
287
static inline void gen_movl_imm_T0(int val)
297 288
{
298
	gen_movl_imm_TN (0, val);
289
    gen_movl_imm_TN(0, val);
299 290
}
300 291

  
301
static inline void gen_movl_reg_TN (int reg, int t)
292
static inline void gen_movl_reg_TN(int reg, int t)
302 293
{
303
	if (reg) gen_op_movl_reg_TN[t][reg]();
304
	else gen_movl_imm_TN (t, 0);
294
    if (reg)
295
	gen_op_movl_reg_TN[t][reg] ();
296
    else
297
	gen_movl_imm_TN(t, 0);
305 298
}
306 299

  
307
static inline void gen_movl_reg_T0 (int reg)
300
static inline void gen_movl_reg_T0(int reg)
308 301
{
309
	gen_movl_reg_TN (reg, 0);
302
    gen_movl_reg_TN(reg, 0);
310 303
}
311 304

  
312
static inline void gen_movl_reg_T1 (int reg)
305
static inline void gen_movl_reg_T1(int reg)
313 306
{
314
	gen_movl_reg_TN (reg, 1);
307
    gen_movl_reg_TN(reg, 1);
315 308
}
316 309

  
317
static inline void gen_movl_reg_T2 (int reg)
310
static inline void gen_movl_reg_T2(int reg)
318 311
{
319
	gen_movl_reg_TN (reg, 2);
312
    gen_movl_reg_TN(reg, 2);
320 313
}
321 314

  
322
static inline void gen_movl_TN_reg (int reg, int t)
315
static inline void gen_movl_TN_reg(int reg, int t)
323 316
{
324
	if (reg) gen_op_movl_TN_reg[t][reg]();
317
    if (reg)
318
	gen_op_movl_TN_reg[t][reg] ();
325 319
}
326 320

  
327
static inline void gen_movl_T0_reg (int reg)
321
static inline void gen_movl_T0_reg(int reg)
328 322
{
329
	gen_movl_TN_reg (reg, 0);
323
    gen_movl_TN_reg(reg, 0);
330 324
}
331 325

  
332
static inline void gen_movl_T1_reg (int reg)
326
static inline void gen_movl_T1_reg(int reg)
333 327
{
334
	gen_movl_TN_reg (reg, 1);
328
    gen_movl_TN_reg(reg, 1);
335 329
}
336 330

  
337
static void do_branch (DisasContext *dc, uint32_t target, uint32_t insn)
331
static void gen_cond(int cond)
338 332
{
339
	unsigned int cond = GET_FIELD (insn, 3, 6), a = (insn & (1<<29)), ib = 0;
340
	target += (uint32_t) dc->pc-4;
341
	if (!a) disas_sparc_insn (dc);
342 333
	switch (cond) {
343
	  case 0x0: gen_op_movl_T0_0 (); break;
344
	  case 0x1: gen_op_eval_be (); break;
345
	  case 0x2: gen_op_eval_ble (); break;
346
	  case 0x3: gen_op_eval_bl (); break;
347
	  case 0x4: gen_op_eval_bleu (); break;
348
	  case 0x5: gen_op_eval_bcs (); break;
349
	  case 0x6: gen_op_eval_bneg (); break;
350
	  case 0x7: gen_op_eval_bvs (); break;
351
	  case 0x8: gen_op_movl_T0_1 (); break;
352
	  case 0x9: gen_op_eval_bne (); break;
353
	  case 0xa: gen_op_eval_bg (); break;
354
	  case 0xb: gen_op_eval_bge (); break;
355
	  case 0xc: gen_op_eval_bgu (); break;
356
	  case 0xd: gen_op_eval_bcc (); break;
357
	  case 0xe: gen_op_eval_bpos (); break;
358
	  case 0xf: gen_op_eval_bvc (); break;
359
	}
360
	if (a && ((cond|0x8) != 0x8)) {
361
		gen_op_generic_branch_a ((uint32_t) dc->tb,
362
				(uint32_t) dc->pc+4, target);
363
		disas_sparc_insn (dc);
364
		ib = 1;
334
        case 0x0:
335
            gen_op_movl_T2_0();
336
            break;
337
	case 0x1:
338
	    gen_op_eval_be();
339
	    break;
340
	case 0x2:
341
	    gen_op_eval_ble();
342
	    break;
343
	case 0x3:
344
	    gen_op_eval_bl();
345
	    break;
346
	case 0x4:
347
	    gen_op_eval_bleu();
348
	    break;
349
	case 0x5:
350
	    gen_op_eval_bcs();
351
	    break;
352
	case 0x6:
353
	    gen_op_eval_bneg();
354
	    break;
355
	case 0x7:
356
	    gen_op_eval_bvs();
357
	    break;
358
        case 0x8:
359
            gen_op_movl_T2_1();
360
            break;
361
	case 0x9:
362
	    gen_op_eval_bne();
363
	    break;
364
	case 0xa:
365
	    gen_op_eval_bg();
366
	    break;
367
	case 0xb:
368
	    gen_op_eval_bge();
369
	    break;
370
	case 0xc:
371
	    gen_op_eval_bgu();
372
	    break;
373
	case 0xd:
374
	    gen_op_eval_bcc();
375
	    break;
376
	case 0xe:
377
	    gen_op_eval_bpos();
378
	    break;
379
        default:
380
	case 0xf:
381
	    gen_op_eval_bvc();
382
	    break;
365 383
	}
366
	else
367
	if (cond && !a) {
368
		gen_op_generic_branch ((uint32_t) dc->tb, (uint32_t) target,
369
			(uint32_t) dc->pc);
370
		ib = 1;
371
	}
372
	if (ib) dc->is_br = DISAS_JUMP;
373 384
}
374 385

  
375
/* target == 0x1 means CALL- else JMPL-instruction */
376
static void do_jump (DisasContext *dc, uint32_t target, uint32_t rd)
386

  
387
static void do_branch(DisasContext * dc, uint32_t target, uint32_t insn)
377 388
{
378
	uint32_t orig_pc = (uint32_t) dc->pc-8;
379
	if (target != 0x1)
380
	 gen_op_generic_jmp_1 (orig_pc, target);
381
	else
382
	 gen_op_generic_jmp_2 (orig_pc);
383
	gen_movl_T1_reg (rd);
384
	dc->is_br = DISAS_JUMP;
385
	gen_op_movl_T0_0 ();
389
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
390
    target += (uint32_t) dc->pc;
391
    if (cond == 0x0) {
392
	/* unconditional not taken */
393
	if (a) {
394
	    dc->pc = dc->npc + 4;
395
	    dc->npc = dc->pc + 4;
396
	} else {
397
	    dc->pc = dc->npc;
398
	    dc->npc = dc->pc + 4;
399
	}
400
    } else if (cond == 0x8) {
401
	/* unconditional taken */
402
	if (a) {
403
	    dc->pc = (uint8_t *) target;
404
	    dc->npc = dc->pc + 4;
405
	} else {
406
	    dc->pc = dc->npc;
407
	    dc->npc = (uint8_t *) target;
408
	}
409
    } else {
410
        gen_cond(cond);
411
	if (a) {
412
	    gen_op_generic_branch_a((uint32_t) target,
413
				    (uint32_t) (dc->npc));
414
            dc->is_br = 1;
415
            dc->pc = NULL;
416
            dc->npc = NULL;
417
	} else {
418
            dc->pc = dc->npc;
419
	    gen_op_generic_branch((uint32_t) target,
420
				  (uint32_t) (dc->npc + 4));
421
            dc->npc = NULL;
422
	}
423
    }
386 424
}
387 425

  
388
#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), b-a)
426
#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
389 427

  
390
static int
391
sign_extend (x, len)
392
	int x, len;
428
static int sign_extend(int x, int len)
393 429
{
394
	int signbit = (1 << (len - 1));
395
	int mask = (signbit << 1) - 1;
396
	return ((x & mask) ^ signbit) - signbit;
430
    len = 32 - len;
431
    return (x << len) >> len;
397 432
}
398 433

  
399
static void disas_sparc_insn (DisasContext *dc)
434
static inline void save_state(DisasContext * dc)
400 435
{
401
	unsigned int insn, opc, rs1, rs2, rd;
436
    gen_op_jmp_im((uint32_t)dc->pc);
437
    if (dc->npc != NULL)
438
        gen_op_movl_npc_im((long) dc->npc);
439
}
402 440

  
403
	if (dc->delay_slot == 1) {
404
		insn = dc->insn;
405
	} else {
406
		if (dc->delay_slot) dc->delay_slot--;
407
		insn = htonl (*(unsigned int *) (dc->pc));
408
		dc->pc += 4;
409
	}
441
static void disas_sparc_insn(DisasContext * dc)
442
{
443
    unsigned int insn, opc, rs1, rs2, rd;
410 444

  
411
	opc = GET_FIELD (insn, 0, 1);
445
    insn = ldl_code(dc->pc);
446
    opc = GET_FIELD(insn, 0, 1);
412 447

  
413
	rd  = GET_FIELD (insn, 2, 6);
414
	switch (opc) {
415
	  case 0: /* branches/sethi */
416
		{
417
			unsigned int xop = GET_FIELD (insn, 7, 9);
418
			int target;
419
			target = GET_FIELD (insn, 10, 31);
420
			switch (xop) {
421
			 case 0x0: case 0x1: /* UNIMPL */
422
				printf ("UNIMPLEMENTED: %p\n", dc->pc-4);
423
				exit (23);
424
				break;
425
			 case 0x2: /* BN+x */
426
			{
427
				target <<= 2;
428
				target = sign_extend (target, 22);
429
				do_branch (dc, target, insn);
430
				break;
431
			}
432
			 case 0x3: /* FBN+x */
433
				break;
434
			 case 0x4: /* SETHI */
435
				gen_movl_imm_T0 (target<<10);
436
				gen_movl_T0_reg (rd);
437
				break;
438
			 case 0x5: /*CBN+x*/
439
				break;
440
			}
441
			break;
442
		}
443
	  case 1: /*CALL*/
448
    rd = GET_FIELD(insn, 2, 6);
449
    switch (opc) {
450
    case 0:			/* branches/sethi */
451
	{
452
	    unsigned int xop = GET_FIELD(insn, 7, 9);
453
	    int target;
454
	    target = GET_FIELD(insn, 10, 31);
455
	    switch (xop) {
456
	    case 0x0:
457
	    case 0x1:		/* UNIMPL */
458
                goto illegal_insn;
459
	    case 0x2:		/* BN+x */
444 460
		{
445
			unsigned int target = GET_FIELDs (insn, 2, 31) << 2;
446
			if (dc->delay_slot) {
447
				do_jump (dc, target, 15);
448
				dc->delay_slot = 0;
449
			} else {
450
				dc->insn = insn;
451
				dc->delay_slot = 2;
452
			}
453
			break;
461
		    target <<= 2;
462
		    target = sign_extend(target, 22);
463
		    do_branch(dc, target, insn);
464
		    goto jmp_insn;
454 465
		}
455
	  case 2: /* FPU & Logical Operations */
456
		{
457
			unsigned int xop = GET_FIELD (insn, 7, 12);
458
			if (xop == 58) { /* generate trap */
459
				dc->is_br = DISAS_JUMP;
460
				gen_op_jmp_im ((uint32_t) dc->pc);
461
				if (IS_IMM) gen_op_trap (GET_FIELD (insn, 25, 31));
462
				/* else XXX*/
463
				gen_op_movl_T0_0 ();
464
				break;
465
			}
466
			if (xop == 0x34 || xop == 0x35) { /* FPU Operations */
467
				exit (33);
468
			}
469
			rs1 = GET_FIELD (insn, 13, 17);
470
			gen_movl_reg_T0 (rs1);
471
			if (IS_IMM) { /* immediate */
472
				rs2 = GET_FIELDs (insn, 20, 31);
473
				gen_movl_imm_T1 (rs2);
474
			} else {              /* register */
475
				rs2 = GET_FIELD (insn, 27, 31);
476
				gen_movl_reg_T1 (rs2);
477
			}
478
			if (xop < 0x20) {
479
			 switch (xop &~ 0x10) {
480
			  case 0x0:
481
				gen_op_add_T1_T0 ();
482
				break;
483
			  case 0x1:
484
				gen_op_and_T1_T0 ();
485
				break;
486
			  case 0x2:
487
				gen_op_or_T1_T0 ();
488
				break;
489
			  case 0x3:
490
				gen_op_xor_T1_T0 ();
491
				break;
492
			  case 0x4:
493
				gen_op_sub_T1_T0 ();
494
				break;
495
			  case 0x5:
496
				gen_op_andn_T1_T0 ();
497
				break;
498
			  case 0x6:
499
				gen_op_orn_T1_T0 ();
500
				break;
501
			  case 0x7:
502
				gen_op_xnor_T1_T0 ();
503
				break;
504
			  case 0x8:
505
				gen_op_addx_T1_T0 ();
506
				break;
507
			  case 0xa:
508
				gen_op_umul_T1_T0 ();
509
				break;
510
			  case 0xb:
511
				gen_op_smul_T1_T0 ();
512
				break;
513
			  case 0xc:
514
				gen_op_subx_T1_T0 ();
515
				break;
516
			  case 0xe:
517
				gen_op_udiv_T1_T0 ();
518
				break;
519
			  case 0xf:
520
				gen_op_sdiv_T1_T0 ();
521
				break;
522
			  default:
523
				exit (17);
524
				break;
525
			 }
526
			 gen_movl_T0_reg (rd);
527
			 if (xop & 0x10) {
528
				gen_op_set_flags ();
529
			 }
530
			} else {
531
			  switch (xop) {
532
				case 0x25: /* SLL */
533
					gen_op_sll ();
534
					break;
535
				case 0x26:
536
					gen_op_srl ();
537
					break;
538
				case 0x27:
539
					gen_op_sra ();
540
					break;
541
				case 0x28: case 0x30:
542
				{
543
					unsigned int rdi = GET_FIELD (insn, 13, 17);
544
					if (!rdi) (xop==0x28?gen_op_rdy ():gen_op_wry());
545
					/* else gen_op_su_trap (); */
546
					break;
547
				}
548
				/* Problem with jmpl: if restore is executed in the delay
549
				   slot, then the wrong registers are beeing used */
550
				case 0x38: /* jmpl */
551
				{
552
					if (dc->delay_slot) {
553
						gen_op_add_T1_T0 ();
554
						do_jump (dc, 1, rd);
555
						dc->delay_slot = 0;
556
					} else {
557
						gen_op_add_T1_T0 ();
558
						gen_op_jmpl ();
559
						dc->insn = insn;
560
						dc->delay_slot = 2;
561
					}
562
					break;
563
				}
564
				case 0x3c: /* save */
565
					gen_op_add_T1_T0 ();
566
					gen_op_save ();
567
					gen_movl_T0_reg (rd);
568
					break;
569
				case 0x3d: /* restore */
570
					gen_op_add_T1_T0 ();
571
					gen_op_restore ();
572
					gen_movl_T0_reg (rd);
573
					break;
574
			  }
575
			}
576
			break;
466
	    case 0x3:		/* FBN+x */
467
		break;
468
	    case 0x4:		/* SETHI */
469
		gen_movl_imm_T0(target << 10);
470
		gen_movl_T0_reg(rd);
471
		break;
472
	    case 0x5:		/*CBN+x */
473
		break;
474
	    }
475
	    break;
476
	}
477
    case 1:
478
	/*CALL*/ {
479
	    unsigned int target = GET_FIELDs(insn, 2, 31) << 2;
480

  
481
	    gen_op_movl_T0_im((long) (dc->pc));
482
	    gen_movl_T0_reg(15);
483
	    target = (long) dc->pc + target;
484
	    dc->pc = dc->npc;
485
	    dc->npc = (uint8_t *) target;
486
	}
487
	goto jmp_insn;
488
    case 2:			/* FPU & Logical Operations */
489
	{
490
	    unsigned int xop = GET_FIELD(insn, 7, 12);
491
	    if (xop == 0x3a) {	/* generate trap */
492
                int cond;
493
                rs1 = GET_FIELD(insn, 13, 17);
494
                gen_movl_reg_T0(rs1);
495
		if (IS_IMM) {
496
                    gen_movl_imm_T1(GET_FIELD(insn, 25, 31));
497
                } else {
498
                    rs2 = GET_FIELD(insn, 27, 31);
499
                    gen_movl_reg_T1(rs2);
500
                }
501
                gen_op_add_T1_T0();
502
                save_state(dc);
503
                cond = GET_FIELD(insn, 3, 6);
504
                if (cond == 0x8) {
505
                    gen_op_trap_T0();
506
                    dc->is_br = 1;
507
                    goto jmp_insn;
508
                } else {
509
                    gen_op_trapcc_T0();
510
                }
511
            } else if (xop == 0x28) {
512
                rs1 = GET_FIELD(insn, 13, 17);
513
                switch(rs1) {
514
                case 0: /* rdy */
515
                    gen_op_rdy();
516
                    gen_movl_T0_reg(rd);
517
                    break;
518
                default:
519
                    goto illegal_insn;
520
                }
521
	    } else if (xop == 0x34 || xop == 0x35) {	/* FPU Operations */
522
                goto illegal_insn;
523
	    } else {
524
                rs1 = GET_FIELD(insn, 13, 17);
525
                gen_movl_reg_T0(rs1);
526
                if (IS_IMM) {	/* immediate */
527
                    rs2 = GET_FIELDs(insn, 19, 31);
528
                    gen_movl_imm_T1(rs2);
529
                } else {		/* register */
530
                    rs2 = GET_FIELD(insn, 27, 31);
531
                    gen_movl_reg_T1(rs2);
532
                }
533
                if (xop < 0x20) {
534
                    switch (xop & ~0x10) {
535
                    case 0x0:
536
                        if (xop & 0x10)
537
                            gen_op_add_T1_T0_cc();
538
                        else
539
                            gen_op_add_T1_T0();
540
                        break;
541
                    case 0x1:
542
                        gen_op_and_T1_T0();
543
                        if (xop & 0x10)
544
                            gen_op_logic_T0_cc();
545
                        break;
546
                    case 0x2:
547
                        gen_op_or_T1_T0();
548
                        if (xop & 0x10)
549
                            gen_op_logic_T0_cc();
550
                        break;
551
                    case 0x3:
552
                        gen_op_xor_T1_T0();
553
                        if (xop & 0x10)
554
                            gen_op_logic_T0_cc();
555
                        break;
556
                    case 0x4:
557
                        if (xop & 0x10)
558
                            gen_op_sub_T1_T0_cc();
559
                        else
560
                            gen_op_sub_T1_T0();
561
                        break;
562
                    case 0x5:
563
                        gen_op_andn_T1_T0();
564
                        if (xop & 0x10)
565
                            gen_op_logic_T0_cc();
566
                        break;
567
                    case 0x6:
568
                        gen_op_orn_T1_T0();
569
                        if (xop & 0x10)
570
                            gen_op_logic_T0_cc();
571
                        break;
572
                    case 0x7:
573
                        gen_op_xnor_T1_T0();
574
                        if (xop & 0x10)
575
                            gen_op_logic_T0_cc();
576
                        break;
577
                    case 0x8:
578
                        gen_op_addx_T1_T0();
579
                        if (xop & 0x10)
580
                            gen_op_set_flags();
581
                        break;
582
                    case 0xa:
583
                        gen_op_umul_T1_T0();
584
                        if (xop & 0x10)
585
                            gen_op_logic_T0_cc();
586
                        break;
587
                    case 0xb:
588
                        gen_op_smul_T1_T0();
589
                        if (xop & 0x10)
590
                            gen_op_logic_T0_cc();
591
                        break;
592
                    case 0xc:
593
                        gen_op_subx_T1_T0();
594
                        if (xop & 0x10)
595
                            gen_op_set_flags();
596
                        break;
597
                    case 0xe:
598
                        gen_op_udiv_T1_T0();
599
                        if (xop & 0x10)
600
                            gen_op_div_cc();
601
                        break;
602
                    case 0xf:
603
                        gen_op_sdiv_T1_T0();
604
                        if (xop & 0x10)
605
                            gen_op_div_cc();
606
                        break;
607
                    default:
608
                        goto illegal_insn;
609
                    }
610
                    gen_movl_T0_reg(rd);
611
                } else {
612
                    switch (xop) {
613
                    case 0x24: /* mulscc */
614
                        gen_op_mulscc_T1_T0();
615
                        gen_movl_T0_reg(rd);
616
                        break;
617
                    case 0x25:	/* SLL */
618
                        gen_op_sll();
619
                        gen_movl_T0_reg(rd);
620
                        break;
621
                    case 0x26:
622
                        gen_op_srl();
623
                        gen_movl_T0_reg(rd);
624
                        break;
625
                    case 0x27:
626
                        gen_op_sra();
627
                        gen_movl_T0_reg(rd);
628
                        break;
629
                    case 0x30:
630
                        {
631
                            gen_op_xor_T1_T0();
632
                            switch(rd) {
633
                            case 0:
634
                                gen_op_wry();
635
                                break;
636
                            default:
637
                                goto illegal_insn;
638
                            }
639
                        }
640
                        break;
641
                    case 0x38:	/* jmpl */
642
                        {
643
                            gen_op_add_T1_T0();
644
                            gen_op_movl_npc_T0();
645
                            if (rd != 0) {
646
                                gen_op_movl_T0_im((long) (dc->pc));
647
                                gen_movl_T0_reg(rd);
648
                            }
649
                            dc->pc = dc->npc;
650
                            dc->npc = NULL;
651
                        }
652
                        goto jmp_insn;
653
                    case 0x3b: /* flush */
654
                        /* nothing to do */
655
                        break;
656
                    case 0x3c:	/* save */
657
                        save_state(dc);
658
                        gen_op_add_T1_T0();
659
                        gen_op_save();
660
                        gen_movl_T0_reg(rd);
661
                        break;
662
                    case 0x3d:	/* restore */
663
                        save_state(dc);
664
                        gen_op_add_T1_T0();
665
                        gen_op_restore();
666
                        gen_movl_T0_reg(rd);
667
                        break;
668
                    default:
669
                        goto illegal_insn;
670
                    }
671
                }
672
            }
673
	    break;
674
	}
675
    case 3:			/* load/store instructions */
676
	{
677
	    unsigned int xop = GET_FIELD(insn, 7, 12);
678
	    rs1 = GET_FIELD(insn, 13, 17);
679
	    gen_movl_reg_T0(rs1);
680
	    if (IS_IMM) {	/* immediate */
681
		rs2 = GET_FIELDs(insn, 19, 31);
682
		gen_movl_imm_T1(rs2);
683
	    } else {		/* register */
684
		rs2 = GET_FIELD(insn, 27, 31);
685
		gen_movl_reg_T1(rs2);
686
	    }
687
	    gen_op_add_T1_T0();
688
	    if (xop < 4 || xop > 7) {
689
		switch (xop) {
690
		case 0x0:	/* load word */
691
		    gen_op_ld();
692
		    break;
693
		case 0x1:	/* load unsigned byte */
694
		    gen_op_ldub();
695
		    break;
696
		case 0x2:	/* load unsigned halfword */
697
		    gen_op_lduh();
698
		    break;
699
		case 0x3:	/* load double word */
700
		    gen_op_ldd();
701
		    gen_movl_T0_reg(rd + 1);
702
		    break;
703
		case 0x9:	/* load signed byte */
704
		    gen_op_ldsb();
705
		    break;
706
		case 0xa:	/* load signed halfword */
707
		    gen_op_ldsh();
708
		    break;
709
		case 0xd:	/* ldstub -- XXX: should be atomically */
710
		    gen_op_ldstub();
711
		    break;
712
		case 0x0f:	/* swap register with memory. Also atomically */
713
		    gen_op_swap();
714
		    break;
577 715
		}
578
	  case 3: /* load/store instructions */
579
		{
580
			unsigned int xop = GET_FIELD (insn, 7, 12);
581
			rs1 = GET_FIELD (insn, 13, 17);
582
			gen_movl_reg_T0 (rs1);
583
			if (IS_IMM) { /* immediate */
584
				rs2 = GET_FIELDs (insn, 20, 31);
585
				gen_movl_imm_T1 (rs2);
586
			} else {              /* register */
587
				rs2 = GET_FIELD (insn, 27, 31);
588
				gen_movl_reg_T1 (rs2);
589
			}
590
			gen_op_add_T1_T0 ();
591
			if (xop < 4 || xop > 7)  {
592
			 switch (xop) {
593
			  case 0x0: /* load word */
594
				gen_op_ld ();
595
				break;
596
			  case 0x1: /* load unsigned byte */
597
				gen_op_ldub ();
598
				break;
599
			  case 0x2: /* load unsigned halfword */
600
				gen_op_lduh ();
601
				break;
602
			  case 0x3: /* load double word */
603
				gen_op_ldd ();
604
				gen_movl_T0_reg (rd+1);
605
				break;
606
			  case 0x9: /* load signed byte */
607
				gen_op_ldsb ();
608
				break;
609
			  case 0xa: /* load signed halfword */
610
				gen_op_ldsh ();
611
				break;
612
			  case 0xd: /* ldstub -- XXX: should be atomically */
613
				gen_op_ldstub ();
614
				break;
615
			  case 0x0f: /* swap register with memory. Also atomically */
616
				gen_op_swap ();
617
				break;
618
			 }
619
			 gen_movl_T1_reg (rd);
620
			} else if (xop < 8) {
621
			 gen_movl_reg_T1 (rd);
622
			 switch (xop) {
623
			  case 0x4:
624
				gen_op_st ();
625
				break;
626
			  case 0x5:
627
				gen_op_stb ();
628
				break;
629
			  case 0x6:
630
				gen_op_sth ();
631
				break;
632
			  case 0x7:
633
				gen_op_st ();
634
				gen_movl_reg_T1 (rd+1);
635
				gen_op_st ();
636
				break;
637
			 }
638
			}
716
		gen_movl_T1_reg(rd);
717
	    } else if (xop < 8) {
718
		gen_movl_reg_T1(rd);
719
		switch (xop) {
720
		case 0x4:
721
		    gen_op_st();
722
		    break;
723
		case 0x5:
724
		    gen_op_stb();
725
		    break;
726
		case 0x6:
727
		    gen_op_sth();
728
		    break;
729
		case 0x7:
730
		    gen_movl_reg_T2(rd + 1);
731
		    gen_op_std();
732
		    break;
639 733
		}
734
	    }
640 735
	}
736
    }
737
    /* default case for non jump instructions */
738
    if (dc->npc != NULL) {
739
	dc->pc = dc->npc;
740
	dc->npc = dc->npc + 4;
741
    } else {
742
	dc->pc = NULL;
743
	gen_op_next_insn();
744
    }
745
  jmp_insn:;
746
    return;
747
 illegal_insn:
748
    gen_op_jmp_im((uint32_t)dc->pc);
749
    if (dc->npc != NULL)
750
        gen_op_movl_npc_im((long) dc->npc);
751
    gen_op_exception(TT_ILL_INSN);
752
    dc->is_br = 1;
641 753
}
642 754

  
643
static inline int gen_intermediate_code_internal (TranslationBlock *tb, int spc)
755
static inline int gen_intermediate_code_internal(TranslationBlock * tb,
756
						 int spc)
644 757
{
645
	uint8_t *pc_start = (uint8_t *) tb->pc;
646
	uint16_t *gen_opc_end;
647
	DisasContext dc;
648

  
649
	memset (&dc, 0, sizeof (dc));
650
	if (spc) {
651
		printf ("SearchPC not yet supported\n");
652
		exit (0);
653
	}
654
	dc.tb = tb;
655
	dc.pc = pc_start;
656

  
657
	gen_opc_ptr = gen_opc_buf;
658
	gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
659
	gen_opparam_ptr = gen_opparam_buf;
660

  
661
	do {
662
		disas_sparc_insn (&dc);
663
	} while (!dc.is_br && (gen_opc_ptr < gen_opc_end) &&
664
		(dc.pc - pc_start) < (TARGET_PAGE_SIZE - 32));
665

  
666
	switch (dc.is_br) {
667
	  case DISAS_JUMP:
668
	  case DISAS_TB_JUMP:
669
		gen_op_exit_tb ();
670
		break;
671
	}
672

  
673
	*gen_opc_ptr = INDEX_op_end;
758
    uint8_t *pc_start, *last_pc;
759
    uint16_t *gen_opc_end;
760
    DisasContext dc1, *dc = &dc1;
761

  
762
    memset(dc, 0, sizeof(DisasContext));
763
    if (spc) {
764
	printf("SearchPC not yet supported\n");
765
	exit(0);
766
    }
767
    dc->tb = tb;
768
    pc_start = (uint8_t *) tb->pc;
769
    dc->pc = pc_start;
770
    dc->npc = (uint8_t *) tb->cs_base;
771

  
772
    gen_opc_ptr = gen_opc_buf;
773
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
774
    gen_opparam_ptr = gen_opparam_buf;
775

  
776
    do {
777
	last_pc = dc->pc;
778
	disas_sparc_insn(dc);
779
	if (dc->is_br)
780
	    break;
781
	/* if the next PC is different, we abort now */
782
	if (dc->pc != (last_pc + 4))
783
	    break;
784
    } while ((gen_opc_ptr < gen_opc_end) &&
785
	     (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
786
    if (dc->pc != NULL)
787
	gen_op_jmp_im((long) dc->pc);
788
    if (dc->npc != NULL)
789
	gen_op_movl_npc_im((long) dc->npc);
790
    gen_op_movl_T0_0();
791
    gen_op_exit_tb();
792

  
793
    *gen_opc_ptr = INDEX_op_end;
674 794
#ifdef DEBUG_DISAS
675
	if (loglevel) {
676
		fprintf (logfile, "--------------\n");
677
		fprintf (logfile, "IN: %s\n", lookup_symbol (pc_start));
678
		disas(logfile, pc_start, dc.pc - pc_start, 0, 0);
679
		fprintf(logfile, "\n");
680
		fprintf(logfile, "OP:\n");
681
		dump_ops(gen_opc_buf, gen_opparam_buf);
682
		fprintf(logfile, "\n");
683
	}
795
    if (loglevel) {
796
	fprintf(logfile, "--------------\n");
797
	fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
798
	disas(logfile, pc_start, last_pc + 4 - pc_start, 0, 0);
799
	fprintf(logfile, "\n");
800
	fprintf(logfile, "OP:\n");
801
	dump_ops(gen_opc_buf, gen_opparam_buf);
802
	fprintf(logfile, "\n");
803
    }
684 804
#endif
685 805

  
686
	return 0;
806
    return 0;
687 807
}
688 808

  
689
int gen_intermediate_code (CPUSPARCState *env, TranslationBlock *tb)
809
int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
690 810
{
691
	return gen_intermediate_code_internal(tb, 0);
811
    return gen_intermediate_code_internal(tb, 0);
692 812
}
693 813

  
694
int gen_intermediate_code_pc (CPUSPARCState *env, TranslationBlock *tb)
814
int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
695 815
{
696
	return gen_intermediate_code_internal(tb, 1);
816
    return gen_intermediate_code_internal(tb, 1);
697 817
}
698 818

  
699
void *mycpu;
700

  
701
CPUSPARCState *cpu_sparc_init (void)
819
CPUSPARCState *cpu_sparc_init(void)
702 820
{
703
	CPUSPARCState *env;
704

  
705
	cpu_exec_init ();
706

  
707
	if (!(env = malloc (sizeof(CPUSPARCState))))
708
		return (NULL);
709
	memset (env, 0, sizeof (*env));
710
	if (!(env->regwptr = malloc (0x2000)))
711
		return (NULL);
712
	memset (env->regwptr, 0, 0x2000);
713
	env->regwptr += 127;
714
	env->user_mode_only = 1;
715
	mycpu = env;
716
	return (env);
821
    CPUSPARCState *env;
822

  
823
    cpu_exec_init();
824

  
825
    if (!(env = malloc(sizeof(CPUSPARCState))))
826
	return (NULL);
827
    memset(env, 0, sizeof(*env));
828
    env->cwp = 0;
829
    env->wim = 1;
830
    env->regwptr = env->regbase + (env->cwp * 16);
831
    env->user_mode_only = 1;
832
    return (env);
717 833
}
718 834

  
719 835
#define GET_FLAG(a,b) ((env->psr & a)?b:'-')
720 836

  
721
void cpu_sparc_dump_state (CPUSPARCState *env, FILE *f, int flags)
837
void cpu_sparc_dump_state(CPUSPARCState * env, FILE * f, int flags)
722 838
{
723
	int i, x;
724

  
725
	fprintf (f, "@PC: %p\n", (void *) env->pc);
726
	fprintf (f, "General Registers:\n");
727
	for (i=0;i<4;i++)
728
		fprintf (f, "%%g%c: %%%08x\t", i+'0', env->gregs[i]);
729
	fprintf (f, "\n");
730
	for (;i<8;i++)
731
		fprintf (f, "%%g%c: %%%08x\t", i+'0', env->gregs[i]);
732
	fprintf (f, "\nCurrent Register Window:\n");
733
	for (x=0;x<3;x++) {
734
	  for (i=0;i<4;i++)
735
		fprintf (f, "%%%c%d: %%%08x\t", (x==0?'o':(x==1?'l':'i')), i, env->regwptr[i+x*8]);
736
	  fprintf (f, "\n");
737
	  for (;i<8;i++)
738
		fprintf (f, "%%%c%d: %%%08x\t", (x==0?'o':x==1?'l':'i'), i, env->regwptr[i+x*8]);
739
	  fprintf (f, "\n");
740
	}
741
	fprintf (f, "PSR: %x -> %c%c%c%c\n", env->psr,
742
			GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
743
			GET_FLAG(PSR_NEG, 'N'),  GET_FLAG(PSR_CARRY, 'C'));
839
    int i, x;
840

  
841
    fprintf(f, "pc: 0x%08x  npc: 0x%08x\n", (int) env->pc, (int) env->npc);
842
    fprintf(f, "General Registers:\n");
843
    for (i = 0; i < 4; i++)
844
	fprintf(f, "%%g%c: 0x%08x\t", i + '0', env->gregs[i]);
845
    fprintf(f, "\n");
846
    for (; i < 8; i++)
847
	fprintf(f, "%%g%c: 0x%08x\t", i + '0', env->gregs[i]);
848
    fprintf(f, "\nCurrent Register Window:\n");
849
    for (x = 0; x < 3; x++) {
850
	for (i = 0; i < 4; i++)
851
	    fprintf(f, "%%%c%d: 0x%08x\t",
852
		    (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i,
853
		    env->regwptr[i + x * 8]);
854
	fprintf(f, "\n");
855
	for (; i < 8; i++)
856
	    fprintf(f, "%%%c%d: 0x%08x\t",
857
		    (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i,
858
		    env->regwptr[i + x * 8]);
859
	fprintf(f, "\n");
860
    }
861
    fprintf(f, "psr: 0x%08x -> %c%c%c%c wim: 0x%08x\n", env->psr | env->cwp,
862
	    GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
863
	    GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
864
            env->wim);
744 865
}

Also available in: Unified diff