1/* CRIS v32 simulator support code
2   Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
3   Contributed by Axis Communications.
4
5This file is part of the GNU simulators.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20/* The infrastructure is based on that of i960.c.  */
21
22#define WANT_CPU_CRISV32F
23
24#define SPECIFIC_U_EXEC_FN
25#define SPECIFIC_U_SKIP4_FN
26#define SPECIFIC_U_CONST16_FN
27#define SPECIFIC_U_CONST32_FN
28#define SPECIFIC_U_MEM_FN
29#define SPECIFIC_U_MOVEM_FN
30#define BASENUM 32
31#include "cris-tmpl.c"
32
33#if WITH_PROFILE_MODEL_P
34
35/* Re-use the bit position for the BZ register, since there are no stall
36   cycles for reading or writing it.  */
37#define CRIS_BZ_REGNO 16
38#define CRIS_MODF_JUMP_MASK (1 << CRIS_BZ_REGNO)
39/* Likewise for the WZ register, marking memory writes.  */
40#define CRIS_WZ_REGNO 20
41#define CRIS_MODF_MEM_WRITE_MASK (1 << CRIS_WZ_REGNO)
42#define CRIS_MOF_REGNO (16 + 7)
43#define CRIS_ALWAYS_CONDITION 14
44
45/* This macro must only be used in context where there's only one
46   dynamic cause for a penalty, except in the u-exec unit.  */
47
48#define PENALIZE1(CNT)					\
49  do							\
50    {							\
51      CPU_CRIS_MISC_PROFILE (current_cpu)->CNT++;	\
52      model_data->prev_prev_prev_modf_regs		\
53	= model_data->prev_prev_modf_regs;		\
54      model_data->prev_prev_modf_regs			\
55	= model_data->prev_modf_regs;			\
56      model_data->prev_modf_regs = 0;			\
57      model_data->prev_prev_prev_movem_dest_regs	\
58	= model_data->prev_prev_movem_dest_regs;	\
59      model_data->prev_prev_movem_dest_regs		\
60	= model_data->prev_movem_dest_regs;		\
61      model_data->prev_movem_dest_regs = 0;		\
62    }							\
63  while (0)
64
65
66/* Model function for u-skip4 unit.  */
67
68int
69MY (XCONCAT3 (f_model_crisv,BASENUM,
70	      _u_skip4)) (SIM_CPU *current_cpu,
71			  const IDESC *idesc ATTRIBUTE_UNUSED,
72			  int unit_num ATTRIBUTE_UNUSED,
73			  int referenced ATTRIBUTE_UNUSED)
74{
75  /* Handle PC not being updated with pbb.  FIXME: What if not pbb?  */
76  CPU (h_pc) += 4;
77  return 0;
78}
79
80/* Model function for u-exec unit.  */
81
82int
83MY (XCONCAT3 (f_model_crisv,BASENUM,
84	      _u_exec)) (SIM_CPU *current_cpu,
85			 const IDESC *idesc ATTRIBUTE_UNUSED,
86			 int unit_num ATTRIBUTE_UNUSED,
87			 int referenced ATTRIBUTE_UNUSED,
88			 INT destreg_in,
89			 INT srcreg,
90			 INT destreg_out)
91{
92  MODEL_CRISV32_DATA *model_data
93    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);
94  UINT modf_regs
95    = ((destreg_out == -1 ? 0 : (1 << destreg_out))
96       | model_data->modf_regs);
97
98  if (srcreg != -1)
99    {
100      if (model_data->prev_movem_dest_regs & (1 << srcreg))
101	{
102	  PENALIZE1 (movemdst_stall_count);
103	  PENALIZE1 (movemdst_stall_count);
104	  PENALIZE1 (movemdst_stall_count);
105	}
106      else if (model_data->prev_prev_movem_dest_regs & (1 << srcreg))
107	{
108	  PENALIZE1 (movemdst_stall_count);
109	  PENALIZE1 (movemdst_stall_count);
110	}
111      else if (model_data->prev_prev_prev_movem_dest_regs & (1 << srcreg))
112	PENALIZE1 (movemdst_stall_count);
113    }
114
115  if (destreg_in != -1)
116    {
117      if (model_data->prev_movem_dest_regs & (1 << destreg_in))
118	{
119	  PENALIZE1 (movemdst_stall_count);
120	  PENALIZE1 (movemdst_stall_count);
121	  PENALIZE1 (movemdst_stall_count);
122	}
123      else if (model_data->prev_prev_movem_dest_regs & (1 << destreg_in))
124	{
125	  PENALIZE1 (movemdst_stall_count);
126	  PENALIZE1 (movemdst_stall_count);
127	}
128      else if (model_data->prev_prev_prev_movem_dest_regs & (1 << destreg_in))
129	PENALIZE1 (movemdst_stall_count);
130    }
131
132  model_data->prev_prev_prev_modf_regs
133    = model_data->prev_prev_modf_regs;
134  model_data->prev_prev_modf_regs = model_data->prev_modf_regs;
135  model_data->prev_modf_regs = modf_regs;
136  model_data->modf_regs = 0;
137
138  model_data->prev_prev_prev_movem_dest_regs
139    = model_data->prev_prev_movem_dest_regs;
140  model_data->prev_prev_movem_dest_regs = model_data->prev_movem_dest_regs;
141  model_data->prev_movem_dest_regs = model_data->movem_dest_regs;
142  model_data->movem_dest_regs = 0;
143
144  /* Handle PC not being updated with pbb.  FIXME: What if not pbb?  */
145  CPU (h_pc) += 2;
146  return 1;
147}
148
149/* Special case used when the destination is a special register.  */
150
151int
152MY (XCONCAT3 (f_model_crisv,BASENUM,
153	      _u_exec_to_sr)) (SIM_CPU *current_cpu,
154			       const IDESC *idesc ATTRIBUTE_UNUSED,
155			       int unit_num ATTRIBUTE_UNUSED,
156			       int referenced ATTRIBUTE_UNUSED,
157			       INT srcreg,
158			       INT specreg)
159{
160  int specdest;
161
162  if (specreg != -1)
163    specdest = specreg + 16;
164  else
165    abort ();
166
167  return MY (XCONCAT3 (f_model_crisv,BASENUM,_u_exec))
168    (current_cpu, NULL, 0, 0, -1, srcreg,
169     /* The positions for constant-zero registers BZ and WZ are recycled
170	for jump and memory-write markers.  We must take precautions
171	here not to add false markers for them.  It might be that the
172	hardware inserts stall cycles for instructions that actually try
173	and write those registers, but we'll burn that bridge when we
174	get to it; we'd have to find other free bits or make new
175	model_data variables.  However, it's doubtful that there will
176	ever be a need to be cycle-correct for useless code, at least in
177	this particular simulator, mainly used for GCC testing.  */
178     specdest == CRIS_BZ_REGNO || specdest == CRIS_WZ_REGNO
179     ? -1 : specdest);
180}
181
182
183/* Special case for movem.  */
184
185int
186MY (XCONCAT3 (f_model_crisv,BASENUM,
187	      _u_exec_movem)) (SIM_CPU *current_cpu,
188			       const IDESC *idesc ATTRIBUTE_UNUSED,
189			       int unit_num ATTRIBUTE_UNUSED,
190			       int referenced ATTRIBUTE_UNUSED,
191			       INT srcreg,
192			       INT destreg_out)
193{
194  return MY (XCONCAT3 (f_model_crisv,BASENUM,_u_exec))
195    (current_cpu, NULL, 0, 0, -1, srcreg, destreg_out);
196}
197
198/* Model function for u-const16 unit.  */
199
200int
201MY (XCONCAT3 (f_model_crisv,BASENUM,
202	      _u_const16)) (SIM_CPU *current_cpu,
203			    const IDESC *idesc ATTRIBUTE_UNUSED,
204			    int unit_num ATTRIBUTE_UNUSED,
205			    int referenced ATTRIBUTE_UNUSED)
206{
207  MODEL_CRISV32_DATA *model_data
208    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);
209
210  /* If the previous insn was a jump of some sort and this insn
211     straddles a cache-line, there's a one-cycle penalty.
212     FIXME: Test-cases for normal const16 and others, like branch.  */
213  if ((model_data->prev_modf_regs & CRIS_MODF_JUMP_MASK)
214      && (CPU (h_pc) & 0x1e) == 0x1e)
215    PENALIZE1 (jumptarget_stall_count);
216
217  /* Handle PC not being updated with pbb.  FIXME: What if not pbb?  */
218  CPU (h_pc) += 2;
219
220  return 0;
221}
222
223/* Model function for u-const32 unit.  */
224
225int
226MY (XCONCAT3 (f_model_crisv,BASENUM,
227	      _u_const32)) (SIM_CPU *current_cpu,
228			    const IDESC *idesc ATTRIBUTE_UNUSED,
229			    int unit_num ATTRIBUTE_UNUSED,
230			    int referenced ATTRIBUTE_UNUSED)
231{
232  MODEL_CRISV32_DATA *model_data
233    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);
234
235  /* If the previous insn was a jump of some sort and this insn
236     straddles a cache-line, there's a one-cycle penalty.  */
237  if ((model_data->prev_modf_regs & CRIS_MODF_JUMP_MASK)
238      && (CPU (h_pc) & 0x1e) == 0x1c)
239    PENALIZE1 (jumptarget_stall_count);
240
241  /* Handle PC not being updated with pbb.  FIXME: What if not pbb?  */
242  CPU (h_pc) += 4;
243
244  return 0;
245}
246
247/* Model function for u-mem unit.  */
248
249int
250MY (XCONCAT3 (f_model_crisv,BASENUM,
251	      _u_mem)) (SIM_CPU *current_cpu,
252			const IDESC *idesc ATTRIBUTE_UNUSED,
253			int unit_num ATTRIBUTE_UNUSED,
254			int referenced ATTRIBUTE_UNUSED,
255			INT srcreg)
256{
257  MODEL_CRISV32_DATA *model_data
258    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);
259
260  if (srcreg == -1)
261    abort ();
262
263  /* If srcreg references a register modified in the previous cycle
264     through other than autoincrement, then there's a penalty: one
265     cycle.  */
266  if (model_data->prev_modf_regs & (1 << srcreg))
267    PENALIZE1 (memsrc_stall_count);
268
269  return 0;
270}
271
272/* Model function for u-mem-r unit.  */
273
274int
275MY (XCONCAT3 (f_model_crisv,BASENUM,
276	      _u_mem_r)) (SIM_CPU *current_cpu,
277			  const IDESC *idesc ATTRIBUTE_UNUSED,
278			  int unit_num ATTRIBUTE_UNUSED,
279			  int referenced ATTRIBUTE_UNUSED)
280{
281  MODEL_CRISV32_DATA *model_data
282    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);
283
284  /* There's a two-cycle penalty for read after a memory write in any of
285     the two previous cycles, known as a cache read-after-write hazard.
286
287     This model function (the model_data member access) depends on being
288     executed before the u-exec unit.  */
289  if ((model_data->prev_modf_regs & CRIS_MODF_MEM_WRITE_MASK)
290      || (model_data->prev_prev_modf_regs & CRIS_MODF_MEM_WRITE_MASK))
291    {
292      PENALIZE1 (memraw_stall_count);
293      PENALIZE1 (memraw_stall_count);
294    }
295
296  return 0;
297}
298
299/* Model function for u-mem-w unit.  */
300
301int
302MY (XCONCAT3 (f_model_crisv,BASENUM,
303	      _u_mem_w)) (SIM_CPU *current_cpu,
304			  const IDESC *idesc ATTRIBUTE_UNUSED,
305			  int unit_num ATTRIBUTE_UNUSED,
306			  int referenced ATTRIBUTE_UNUSED)
307{
308  MODEL_CRISV32_DATA *model_data
309    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);
310
311  /* Mark that memory has been written.  This model function (the
312     model_data member access) depends on being executed after the
313     u-exec unit.  */
314  model_data->prev_modf_regs |= CRIS_MODF_MEM_WRITE_MASK;
315
316  return 0;
317}
318
319/* Model function for u-movem-rtom unit.  */
320
321int
322MY (XCONCAT3 (f_model_crisv,BASENUM,
323	      _u_movem_rtom)) (SIM_CPU *current_cpu,
324			       const IDESC *idesc ATTRIBUTE_UNUSED,
325			       int unit_num ATTRIBUTE_UNUSED,
326			       int referenced ATTRIBUTE_UNUSED,
327			       /* Deliberate order.  */
328			       INT addrreg, INT limreg)
329{
330  USI addr;
331  MODEL_CRISV32_DATA *model_data
332    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);
333
334  if (limreg == -1 || addrreg == -1)
335    abort ();
336
337  addr = GET_H_GR (addrreg);
338
339  /* The movem-to-memory instruction must not move a register modified
340     in one of the previous two cycles.  Enforce by adding penalty
341     cycles.  */
342  if (model_data->prev_modf_regs & ((1 << (limreg + 1)) - 1))
343    {
344      PENALIZE1 (movemsrc_stall_count);
345      PENALIZE1 (movemsrc_stall_count);
346    }
347  else if (model_data->prev_prev_modf_regs & ((1 << (limreg + 1)) - 1))
348    PENALIZE1 (movemsrc_stall_count);
349
350  /* One-cycle penalty for each cache-line straddled.  Use the
351     documented expressions.  Unfortunately no penalty cycles are
352     eliminated by any penalty cycles above.  We file these numbers
353     separately, since they aren't schedulable for all cases.  */
354  if ((addr >> 5) == (((addr + 4 * (limreg + 1)) - 1) >> 5))
355    ;
356  else if ((addr >> 5) == (((addr + 4 * (limreg + 1)) - 1) >> 5) - 1)
357    PENALIZE1 (movemaddr_stall_count);
358  else if ((addr >> 5) == (((addr + 4 * (limreg + 1)) - 1) >> 5) - 2)
359    {
360      PENALIZE1 (movemaddr_stall_count);
361      PENALIZE1 (movemaddr_stall_count);
362    }
363  else
364    abort ();
365
366  return 0;
367}
368
369/* Model function for u-movem-mtor unit.  */
370
371int
372MY (XCONCAT3 (f_model_crisv,BASENUM,
373	      _u_movem_mtor)) (SIM_CPU *current_cpu,
374			       const IDESC *idesc ATTRIBUTE_UNUSED,
375			       int unit_num ATTRIBUTE_UNUSED,
376			       int referenced ATTRIBUTE_UNUSED,
377			       /* Deliberate order.  */
378			       INT addrreg, INT limreg)
379{
380  USI addr;
381  int nregs = limreg + 1;
382  MODEL_CRISV32_DATA *model_data
383    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);
384
385  if (limreg == -1 || addrreg == -1)
386    abort ();
387
388  addr = GET_H_GR (addrreg);
389
390  /* One-cycle penalty for each cache-line straddled.  Use the
391     documented expressions.  One cycle is the norm; more cycles are
392     counted as penalties.  Unfortunately no penalty cycles here
393     eliminate penalty cycles indicated in ->movem_dest_regs.  */
394  if ((addr >> 5) == (((addr + 4 * nregs) - 1) >> 5) - 1)
395    PENALIZE1 (movemaddr_stall_count);
396  else if ((addr >> 5) == (((addr + 4 * nregs) - 1) >> 5) - 2)
397    {
398      PENALIZE1 (movemaddr_stall_count);
399      PENALIZE1 (movemaddr_stall_count);
400    }
401
402  model_data->modf_regs |= ((1 << nregs) - 1);
403  model_data->movem_dest_regs  |= ((1 << nregs) - 1);
404  return 0;
405}
406
407
408/* Model function for u-branch unit.
409   FIXME: newpc and cc are always wrong.  */
410
411int
412MY (XCONCAT3 (f_model_crisv,BASENUM,_u_branch)) (SIM_CPU *current_cpu,
413						 const IDESC *idesc,
414						 int unit_num, int referenced)
415{
416  CRIS_MISC_PROFILE *profp = CPU_CRIS_MISC_PROFILE (current_cpu);
417  USI pc = profp->old_pc;
418  MODEL_CRISV32_DATA *model_data
419    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);
420  int taken = profp->branch_taken;
421  int branch_index = (pc & (N_CRISV32_BRANCH_PREDICTORS - 1)) >> 1;
422  int pred_taken = (profp->branch_predictors[branch_index] & 2) != 0;
423
424  if (taken != pred_taken)
425    {
426      PENALIZE1 (branch_stall_count);
427      PENALIZE1 (branch_stall_count);
428    }
429
430  if (taken)
431    {
432      if (profp->branch_predictors[branch_index] < 3)
433	profp->branch_predictors[branch_index]++;
434
435      return MY (XCONCAT3 (f_model_crisv,BASENUM,_u_jump))
436	(current_cpu, idesc, unit_num, referenced, -1);
437    }
438
439  if (profp->branch_predictors[branch_index] != 0)
440    profp->branch_predictors[branch_index]--;
441
442  return 0;
443}
444
445/* Model function for u-jump-r unit.  */
446
447int
448MY (XCONCAT3 (f_model_crisv,BASENUM,
449	      _u_jump_r)) (SIM_CPU *current_cpu,
450			   const IDESC *idesc ATTRIBUTE_UNUSED,
451			   int unit_num ATTRIBUTE_UNUSED,
452			   int referenced ATTRIBUTE_UNUSED,
453			   int regno)
454{
455  MODEL_CRISV32_DATA *model_data
456    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);
457
458  if (regno == -1)
459    abort ();
460
461  /* For jump-to-register, the register must not have been modified the
462     last two cycles.  Penalty: two cycles from the modifying insn.  */
463  if ((1 << regno) & model_data->prev_modf_regs)
464    {
465      PENALIZE1 (jumpsrc_stall_count);
466      PENALIZE1 (jumpsrc_stall_count);
467    }
468  else if ((1 << regno) & model_data->prev_prev_modf_regs)
469    PENALIZE1 (jumpsrc_stall_count);
470
471  return 0;
472}
473
474/* Model function for u-jump-sr unit.  */
475
476int
477MY (XCONCAT3 (f_model_crisv,BASENUM,_u_jump_sr)) (SIM_CPU *current_cpu,
478						  const IDESC *idesc,
479						  int unit_num, int referenced,
480						  int sr_regno)
481{
482  int regno;
483
484  MODEL_CRISV32_DATA *model_data
485    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);
486
487  if (sr_regno == -1)
488    abort ();
489
490  regno = sr_regno + 16;
491
492  /* For jump-to-register, the register must not have been modified the
493     last two cycles.  Penalty: two cycles from the modifying insn.  */
494  if ((1 << regno) & model_data->prev_modf_regs)
495    {
496      PENALIZE1 (jumpsrc_stall_count);
497      PENALIZE1 (jumpsrc_stall_count);
498    }
499  else if ((1 << regno) & model_data->prev_prev_modf_regs)
500    PENALIZE1 (jumpsrc_stall_count);
501
502  return
503    MY (XCONCAT3 (f_model_crisv,BASENUM,_u_jump)) (current_cpu, idesc,
504						   unit_num, referenced, -1);
505}
506
507/* Model function for u-jump unit.  */
508
509int
510MY (XCONCAT3 (f_model_crisv,BASENUM,
511	      _u_jump)) (SIM_CPU *current_cpu,
512			 const IDESC *idesc ATTRIBUTE_UNUSED,
513			 int unit_num ATTRIBUTE_UNUSED,
514			 int referenced ATTRIBUTE_UNUSED,
515			 int out_sr_regno)
516{
517  MODEL_CRISV32_DATA *model_data
518    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);
519
520  /* Mark that we made a jump.  */
521  model_data->modf_regs
522    |= (CRIS_MODF_JUMP_MASK
523	| (out_sr_regno == -1 || out_sr_regno == CRIS_BZ_REGNO
524	   ? 0 : (1 << (out_sr_regno + 16))));
525  return 0;
526}
527
528/* Model function for u-multiply unit.  */
529
530int
531MY (XCONCAT3 (f_model_crisv,BASENUM,
532	      _u_multiply)) (SIM_CPU *current_cpu,
533			     const IDESC *idesc ATTRIBUTE_UNUSED,
534			     int unit_num ATTRIBUTE_UNUSED,
535			     int referenced ATTRIBUTE_UNUSED,
536			     int srcreg, int destreg)
537{
538  MODEL_CRISV32_DATA *model_data
539    = (MODEL_CRISV32_DATA *) CPU_MODEL_DATA (current_cpu);
540
541  /* Sanity-check for cases that should never happen.  */
542  if (srcreg == -1 || destreg == -1)
543    abort ();
544
545  /* This takes extra cycles when one of the inputs has been modified
546     through other than autoincrement in the previous cycle.  Penalty:
547     one cycle.  */
548  if (((1 << srcreg) | (1 << destreg)) & model_data->prev_modf_regs)
549    PENALIZE1 (mulsrc_stall_count);
550
551  /* We modified the multiplication destination (marked in u-exec) and
552     the MOF register.  */
553  model_data->modf_regs |= (1 << CRIS_MOF_REGNO);
554  return 0;
555}
556
557#endif /* WITH_PROFILE_MODEL_P */
558
559int
560MY (deliver_interrupt) (SIM_CPU *current_cpu,
561			enum cris_interrupt_type type,
562			unsigned int vec)
563{
564  unsigned32 old_ccs, shifted_ccs, new_ccs;
565  unsigned char entryaddr_le[4];
566  int was_user;
567  SIM_DESC sd = CPU_STATE (current_cpu);
568  unsigned32 entryaddr;
569
570  /* We haven't implemented other interrupt-types yet.  */
571  if (type != CRIS_INT_INT)
572    abort ();
573
574  /* We're called outside of branch delay slots etc, so we don't check
575     for that.  */
576  if (!GET_H_IBIT_V32 ())
577    return 0;
578
579  old_ccs = GET_H_SR_V32 (H_SR_CCS);
580  shifted_ccs = (old_ccs << 10) & ((1 << 30) - 1);
581
582  /* The M bit is handled by code below and the M bit setter function, but
583     we need to preserve the Q bit.  */
584  new_ccs = shifted_ccs | (old_ccs & (unsigned32) 0x80000000UL);
585  was_user = GET_H_UBIT_V32 ();
586
587  /* We need to force kernel mode since the setter method doesn't allow
588     it.  Then we can use setter methods at will, since they then
589     recognize that we're in kernel mode.  */
590  CPU (h_ubit_v32) = 0;
591
592  SET_H_SR (H_SR_CCS, new_ccs);
593
594  if (was_user)
595    {
596      /* These methods require that user mode is unset.  */
597      SET_H_SR (H_SR_USP, GET_H_GR (H_GR_SP));
598      SET_H_GR (H_GR_SP, GET_H_KERNEL_SP ());
599    }
600
601  /* ERP setting is simplified by not taking interrupts in delay-slots
602     or when halting.  */
603  /* For all other exceptions than guru and NMI, store the return
604     address in ERP and set EXS and EXD here.  */
605  SET_H_SR (H_SR_ERP, GET_H_PC ());
606
607  /* Simplified by not having exception types (fault indications).  */
608  SET_H_SR_V32 (H_SR_EXS, (vec * 256));
609  SET_H_SR_V32 (H_SR_EDA, 0);
610
611  if (sim_core_read_buffer (sd,
612			    current_cpu,
613			    read_map, entryaddr_le,
614			    GET_H_SR (H_SR_EBP) + vec * 4, 4) == 0)
615    {
616      /* Nothing to do actually; either abort or send a signal.  */
617      sim_core_signal (sd, current_cpu, CIA_GET (current_cpu), 0, 4,
618		       GET_H_SR (H_SR_EBP) + vec * 4,
619		       read_transfer, sim_core_unmapped_signal);
620      return 0;
621    }
622
623  entryaddr = bfd_getl32 (entryaddr_le);
624  SET_H_PC (entryaddr);
625
626  return 1;
627}
628