5 #include "sim-options.h"
9 #include "sim-assert.h"
30 /* simulation target board. NULL=default configuration */
31 static char* board
= NULL
;
33 static DECLARE_OPTION_HANDLER (mn10300_option_handler
);
36 OPTION_BOARD
= OPTION_START
,
40 mn10300_option_handler (SIM_DESC sd
,
53 board
= zalloc(strlen(arg
) + 1);
63 static const OPTION mn10300_options
[] =
65 #define BOARD_AM32 "stdeval1"
66 { {"board", required_argument
, NULL
, OPTION_BOARD
},
67 '\0', "none" /* rely on compile-time string concatenation for other options */
69 , "Customize simulation for a particular board.", mn10300_option_handler
},
71 { {NULL
, no_argument
, NULL
, 0}, '\0', NULL
, NULL
, NULL
}
74 /* For compatibility */
78 mn10300_pc_get (sim_cpu
*cpu
)
84 mn10300_pc_set (sim_cpu
*cpu
, sim_cia pc
)
89 static int mn10300_reg_fetch (SIM_CPU
*, int, unsigned char *, int);
90 static int mn10300_reg_store (SIM_CPU
*, int, unsigned char *, int);
92 /* These default values correspond to expected usage for the chip. */
95 sim_open (SIM_OPEN_KIND kind
,
101 SIM_DESC sd
= sim_state_alloc (kind
, cb
);
103 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
105 /* The cpu data is kept in a separately allocated chunk of memory. */
106 if (sim_cpu_alloc_all (sd
, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK
)
109 /* for compatibility */
112 /* FIXME: should be better way of setting up interrupts. For
113 moment, only support watchpoints causing a breakpoint (gdb
115 STATE_WATCHPOINTS (sd
)->pc
= &(PC
);
116 STATE_WATCHPOINTS (sd
)->sizeof_pc
= sizeof (PC
);
117 STATE_WATCHPOINTS (sd
)->interrupt_handler
= NULL
;
118 STATE_WATCHPOINTS (sd
)->interrupt_names
= NULL
;
120 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
122 sim_add_option_table (sd
, NULL
, mn10300_options
);
124 /* Allocate core managed memory */
125 sim_do_command (sd
, "memory region 0,0x100000");
126 sim_do_command (sd
, "memory region 0x40000000,0x200000");
128 /* The parser will print an error message for us, so we silently return. */
129 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
131 /* Uninstall the modules to avoid memory leaks,
132 file descriptor leaks, etc. */
133 sim_module_uninstall (sd
);
138 && (strcmp(board
, BOARD_AM32
) == 0 ) )
141 STATE_ENVIRONMENT (sd
) = OPERATING_ENVIRONMENT
;
143 sim_do_command (sd
, "memory region 0x44000000,0x40000");
144 sim_do_command (sd
, "memory region 0x48000000,0x400000");
146 /* device support for mn1030002 */
147 /* interrupt controller */
149 sim_hw_parse (sd
, "/mn103int@0x34000100/reg 0x34000100 0x7C 0x34000200 0x8 0x34000280 0x8");
151 /* DEBUG: NMI input's */
152 sim_hw_parse (sd
, "/glue@0x30000000/reg 0x30000000 12");
153 sim_hw_parse (sd
, "/glue@0x30000000 > int0 nmirq /mn103int");
154 sim_hw_parse (sd
, "/glue@0x30000000 > int1 watchdog /mn103int");
155 sim_hw_parse (sd
, "/glue@0x30000000 > int2 syserr /mn103int");
157 /* DEBUG: ACK input */
158 sim_hw_parse (sd
, "/glue@0x30002000/reg 0x30002000 4");
159 sim_hw_parse (sd
, "/glue@0x30002000 > int ack /mn103int");
161 /* DEBUG: LEVEL output */
162 sim_hw_parse (sd
, "/glue@0x30004000/reg 0x30004000 8");
163 sim_hw_parse (sd
, "/mn103int > nmi int0 /glue@0x30004000");
164 sim_hw_parse (sd
, "/mn103int > level int1 /glue@0x30004000");
166 /* DEBUG: A bunch of interrupt inputs */
167 sim_hw_parse (sd
, "/glue@0x30006000/reg 0x30006000 32");
168 sim_hw_parse (sd
, "/glue@0x30006000 > int0 irq-0 /mn103int");
169 sim_hw_parse (sd
, "/glue@0x30006000 > int1 irq-1 /mn103int");
170 sim_hw_parse (sd
, "/glue@0x30006000 > int2 irq-2 /mn103int");
171 sim_hw_parse (sd
, "/glue@0x30006000 > int3 irq-3 /mn103int");
172 sim_hw_parse (sd
, "/glue@0x30006000 > int4 irq-4 /mn103int");
173 sim_hw_parse (sd
, "/glue@0x30006000 > int5 irq-5 /mn103int");
174 sim_hw_parse (sd
, "/glue@0x30006000 > int6 irq-6 /mn103int");
175 sim_hw_parse (sd
, "/glue@0x30006000 > int7 irq-7 /mn103int");
177 /* processor interrupt device */
180 sim_hw_parse (sd
, "/mn103cpu@0x20000000");
181 sim_hw_parse (sd
, "/mn103cpu@0x20000000/reg 0x20000000 0x42");
183 /* DEBUG: ACK output wired upto a glue device */
184 sim_hw_parse (sd
, "/glue@0x20002000");
185 sim_hw_parse (sd
, "/glue@0x20002000/reg 0x20002000 4");
186 sim_hw_parse (sd
, "/mn103cpu > ack int0 /glue@0x20002000");
188 /* DEBUG: RESET/NMI/LEVEL wired up to a glue device */
189 sim_hw_parse (sd
, "/glue@0x20004000");
190 sim_hw_parse (sd
, "/glue@0x20004000/reg 0x20004000 12");
191 sim_hw_parse (sd
, "/glue@0x20004000 > int0 reset /mn103cpu");
192 sim_hw_parse (sd
, "/glue@0x20004000 > int1 nmi /mn103cpu");
193 sim_hw_parse (sd
, "/glue@0x20004000 > int2 level /mn103cpu");
195 /* REAL: The processor wired up to the real interrupt controller */
196 sim_hw_parse (sd
, "/mn103cpu > ack ack /mn103int");
197 sim_hw_parse (sd
, "/mn103int > level level /mn103cpu");
198 sim_hw_parse (sd
, "/mn103int > nmi nmi /mn103cpu");
204 sim_hw_parse (sd
, "/pal@0x31000000");
205 sim_hw_parse (sd
, "/pal@0x31000000/reg 0x31000000 64");
206 sim_hw_parse (sd
, "/pal@0x31000000/poll? true");
208 /* DEBUG: PAL wired up to a glue device */
209 sim_hw_parse (sd
, "/glue@0x31002000");
210 sim_hw_parse (sd
, "/glue@0x31002000/reg 0x31002000 16");
211 sim_hw_parse (sd
, "/pal@0x31000000 > countdown int0 /glue@0x31002000");
212 sim_hw_parse (sd
, "/pal@0x31000000 > timer int1 /glue@0x31002000");
213 sim_hw_parse (sd
, "/pal@0x31000000 > int int2 /glue@0x31002000");
214 sim_hw_parse (sd
, "/glue@0x31002000 > int0 int3 /glue@0x31002000");
215 sim_hw_parse (sd
, "/glue@0x31002000 > int1 int3 /glue@0x31002000");
216 sim_hw_parse (sd
, "/glue@0x31002000 > int2 int3 /glue@0x31002000");
218 /* REAL: The PAL wired up to the real interrupt controller */
219 sim_hw_parse (sd
, "/pal@0x31000000 > countdown irq-0 /mn103int");
220 sim_hw_parse (sd
, "/pal@0x31000000 > timer irq-1 /mn103int");
221 sim_hw_parse (sd
, "/pal@0x31000000 > int irq-2 /mn103int");
223 /* 8 and 16 bit timers */
224 sim_hw_parse (sd
, "/mn103tim@0x34001000/reg 0x34001000 36 0x34001080 100 0x34004000 16");
226 /* Hook timer interrupts up to interrupt controller */
227 sim_hw_parse (sd
, "/mn103tim > timer-0-underflow timer-0-underflow /mn103int");
228 sim_hw_parse (sd
, "/mn103tim > timer-1-underflow timer-1-underflow /mn103int");
229 sim_hw_parse (sd
, "/mn103tim > timer-2-underflow timer-2-underflow /mn103int");
230 sim_hw_parse (sd
, "/mn103tim > timer-3-underflow timer-3-underflow /mn103int");
231 sim_hw_parse (sd
, "/mn103tim > timer-4-underflow timer-4-underflow /mn103int");
232 sim_hw_parse (sd
, "/mn103tim > timer-5-underflow timer-5-underflow /mn103int");
233 sim_hw_parse (sd
, "/mn103tim > timer-6-underflow timer-6-underflow /mn103int");
234 sim_hw_parse (sd
, "/mn103tim > timer-6-compare-a timer-6-compare-a /mn103int");
235 sim_hw_parse (sd
, "/mn103tim > timer-6-compare-b timer-6-compare-b /mn103int");
238 /* Serial devices 0,1,2 */
239 sim_hw_parse (sd
, "/mn103ser@0x34000800/reg 0x34000800 48");
240 sim_hw_parse (sd
, "/mn103ser@0x34000800/poll? true");
242 /* Hook serial interrupts up to interrupt controller */
243 sim_hw_parse (sd
, "/mn103ser > serial-0-receive serial-0-receive /mn103int");
244 sim_hw_parse (sd
, "/mn103ser > serial-0-transmit serial-0-transmit /mn103int");
245 sim_hw_parse (sd
, "/mn103ser > serial-1-receive serial-1-receive /mn103int");
246 sim_hw_parse (sd
, "/mn103ser > serial-1-transmit serial-1-transmit /mn103int");
247 sim_hw_parse (sd
, "/mn103ser > serial-2-receive serial-2-receive /mn103int");
248 sim_hw_parse (sd
, "/mn103ser > serial-2-transmit serial-2-transmit /mn103int");
250 sim_hw_parse (sd
, "/mn103iop@0x36008000/reg 0x36008000 8 0x36008020 8 0x36008040 0xc 0x36008060 8 0x36008080 8");
252 /* Memory control registers */
253 sim_do_command (sd
, "memory region 0x32000020,0x30");
254 /* Cache control register */
255 sim_do_command (sd
, "memory region 0x20000070,0x4");
256 /* Cache purge regions */
257 sim_do_command (sd
, "memory region 0x28400000,0x800");
258 sim_do_command (sd
, "memory region 0x28401000,0x800");
260 sim_do_command (sd
, "memory region 0x32000100,0xF");
261 sim_do_command (sd
, "memory region 0x32000200,0xF");
262 sim_do_command (sd
, "memory region 0x32000400,0xF");
263 sim_do_command (sd
, "memory region 0x32000800,0xF");
269 sim_io_eprintf (sd
, "Error: Board `%s' unknown.\n", board
);
276 /* check for/establish the a reference program image */
277 if (sim_analyze_program (sd
,
278 (STATE_PROG_ARGV (sd
) != NULL
279 ? *STATE_PROG_ARGV (sd
)
283 sim_module_uninstall (sd
);
287 /* establish any remaining configuration options */
288 if (sim_config (sd
) != SIM_RC_OK
)
290 sim_module_uninstall (sd
);
294 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
296 /* Uninstall the modules to avoid memory leaks,
297 file descriptor leaks, etc. */
298 sim_module_uninstall (sd
);
303 /* set machine specific configuration */
304 /* STATE_CPU (sd, 0)->psw_mask = (PSW_NP | PSW_EP | PSW_ID | PSW_SAT */
305 /* | PSW_CY | PSW_OV | PSW_S | PSW_Z); */
307 /* CPU specific initialization. */
308 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
310 SIM_CPU
*cpu
= STATE_CPU (sd
, i
);
312 CPU_REG_FETCH (cpu
) = mn10300_reg_fetch
;
313 CPU_REG_STORE (cpu
) = mn10300_reg_store
;
314 CPU_PC_FETCH (cpu
) = mn10300_pc_get
;
315 CPU_PC_STORE (cpu
) = mn10300_pc_set
;
322 sim_create_inferior (SIM_DESC sd
,
323 struct bfd
*prog_bfd
,
327 memset (&State
, 0, sizeof (State
));
328 if (prog_bfd
!= NULL
) {
329 PC
= bfd_get_start_address (prog_bfd
);
333 CPU_PC_SET (STATE_CPU (sd
, 0), (unsigned64
) PC
);
335 if (STATE_ARCHITECTURE (sd
)->mach
== bfd_mach_am33_2
)
341 /* FIXME These would more efficient to use than load_mem/store_mem,
342 but need to be changed to use the memory map. */
345 mn10300_reg_fetch (SIM_CPU
*cpu
, int rn
, unsigned char *memory
, int length
)
347 reg_t reg
= State
.regs
[rn
];
357 mn10300_reg_store (SIM_CPU
*cpu
, int rn
, unsigned char *memory
, int length
)
360 State
.regs
[rn
] = (a
[3] << 24) + (a
[2] << 16) + (a
[1] << 8) + a
[0];
365 mn10300_core_signal (SIM_DESC sd
,
371 transfer_type transfer
,
372 sim_core_signals sig
)
374 const char *copy
= (transfer
== read_transfer
? "read" : "write");
375 address_word ip
= CIA_ADDR (cia
);
379 case sim_core_unmapped_signal
:
380 sim_io_eprintf (sd
, "mn10300-core: %d byte %s to unmapped address 0x%lx at 0x%lx\n",
382 (unsigned long) addr
, (unsigned long) ip
);
383 program_interrupt(sd
, cpu
, cia
, SIM_SIGSEGV
);
386 case sim_core_unaligned_signal
:
387 sim_io_eprintf (sd
, "mn10300-core: %d byte %s to unaligned address 0x%lx at 0x%lx\n",
389 (unsigned long) addr
, (unsigned long) ip
);
390 program_interrupt(sd
, cpu
, cia
, SIM_SIGBUS
);
394 sim_engine_abort (sd
, cpu
, cia
,
395 "mn10300_core_signal - internal error - bad switch");
401 program_interrupt (SIM_DESC sd
,
408 static int in_interrupt
= 0;
410 #ifdef SIM_CPU_EXCEPTION_TRIGGER
411 SIM_CPU_EXCEPTION_TRIGGER(sd
,cpu
,cia
);
414 /* avoid infinite recursion */
416 sim_io_printf (sd
, "ERROR: recursion in program_interrupt during software exception dispatch.");
420 /* copy NMI handler code from dv-mn103cpu.c */
421 store_word (SP
- 4, CPU_PC_GET (cpu
));
422 store_half (SP
- 8, PSW
);
424 /* Set the SYSEF flag in NMICR by backdoor method. See
425 dv-mn103int.c:write_icr(). This is necessary because
426 software exceptions are not modelled by actually talking to
427 the interrupt controller, so it cannot set its own SYSEF
429 if ((NULL
!= board
) && (strcmp(board
, BOARD_AM32
) == 0))
430 store_byte (0x34000103, 0x04);
435 CPU_PC_SET (cpu
, 0x40000008);
438 sim_engine_halt(sd
, cpu
, NULL
, cia
, sim_stopped
, sig
);
443 mn10300_cpu_exception_trigger(SIM_DESC sd
, sim_cpu
* cpu
, address_word cia
)
447 if(State
.exc_suspended
> 0)
448 sim_io_eprintf(sd
, "Warning, nested exception triggered (%d)\n", State
.exc_suspended
);
450 CPU_PC_SET (cpu
, cia
);
451 memcpy(State
.exc_trigger_regs
, State
.regs
, sizeof(State
.exc_trigger_regs
));
452 State
.exc_suspended
= 0;
456 mn10300_cpu_exception_suspend(SIM_DESC sd
, sim_cpu
* cpu
, int exception
)
460 if(State
.exc_suspended
> 0)
461 sim_io_eprintf(sd
, "Warning, nested exception signal (%d then %d)\n",
462 State
.exc_suspended
, exception
);
464 memcpy(State
.exc_suspend_regs
, State
.regs
, sizeof(State
.exc_suspend_regs
));
465 memcpy(State
.regs
, State
.exc_trigger_regs
, sizeof(State
.regs
));
466 CPU_PC_SET (cpu
, PC
); /* copy PC back from new State.regs */
467 State
.exc_suspended
= exception
;
471 mn10300_cpu_exception_resume(SIM_DESC sd
, sim_cpu
* cpu
, int exception
)
475 if(exception
== 0 && State
.exc_suspended
> 0)
477 if(State
.exc_suspended
!= SIGTRAP
) /* warn not for breakpoints */
478 sim_io_eprintf(sd
, "Warning, resuming but ignoring pending exception signal (%d)\n",
479 State
.exc_suspended
);
481 else if(exception
!= 0 && State
.exc_suspended
> 0)
483 if(exception
!= State
.exc_suspended
)
484 sim_io_eprintf(sd
, "Warning, resuming with mismatched exception signal (%d vs %d)\n",
485 State
.exc_suspended
, exception
);
487 memcpy(State
.regs
, State
.exc_suspend_regs
, sizeof(State
.regs
));
488 CPU_PC_SET (cpu
, PC
); /* copy PC back from new State.regs */
490 else if(exception
!= 0 && State
.exc_suspended
== 0)
492 sim_io_eprintf(sd
, "Warning, ignoring spontanous exception signal (%d)\n", exception
);
494 State
.exc_suspended
= 0;
497 /* This is called when an FP instruction is issued when the FP unit is
498 disabled, i.e., the FE bit of PSW is zero. It raises interrupt
501 fpu_disabled_exception (SIM_DESC sd
, sim_cpu
*cpu
, sim_cia cia
)
503 sim_io_eprintf(sd
, "FPU disabled exception\n");
504 program_interrupt (sd
, cpu
, cia
, SIM_SIGFPE
);
507 /* This is called when the FP unit is enabled but one of the
508 unimplemented insns is issued. It raises interrupt code 0x1c8. */
510 fpu_unimp_exception (SIM_DESC sd
, sim_cpu
*cpu
, sim_cia cia
)
512 sim_io_eprintf(sd
, "Unimplemented FPU instruction exception\n");
513 program_interrupt (sd
, cpu
, cia
, SIM_SIGFPE
);
516 /* This is called at the end of any FP insns that may have triggered
517 FP exceptions. If no exception is enabled, it returns immediately.
518 Otherwise, it raises an exception code 0x1d0. */
520 fpu_check_signal_exception (SIM_DESC sd
, sim_cpu
*cpu
, sim_cia cia
)
522 if ((FPCR
& EC_MASK
) == 0)
525 sim_io_eprintf(sd
, "FPU %s%s%s%s%s exception\n",
526 (FPCR
& EC_V
) ? "V" : "",
527 (FPCR
& EC_Z
) ? "Z" : "",
528 (FPCR
& EC_O
) ? "O" : "",
529 (FPCR
& EC_U
) ? "U" : "",
530 (FPCR
& EC_I
) ? "I" : "");
531 program_interrupt (sd
, cpu
, cia
, SIM_SIGFPE
);
534 /* Convert a 32-bit single-precision FP value in the target platform
535 format to a sim_fpu value. */
537 reg2val_32 (const void *reg
, sim_fpu
*val
)
539 FS2FPU (*(reg_t
*)reg
, *val
);
542 /* Round the given sim_fpu value to single precision, following the
543 target platform rounding and denormalization conventions. On
544 AM33/2.0, round_near is the only rounding mode. */
546 round_32 (sim_fpu
*val
)
548 return sim_fpu_round_32 (val
, sim_fpu_round_near
, sim_fpu_denorm_zero
);
551 /* Convert a sim_fpu value to the 32-bit single-precision target
554 val2reg_32 (const sim_fpu
*val
, void *reg
)
556 FPU2FS (*val
, *(reg_t
*)reg
);
559 /* Define the 32-bit single-precision conversion and rounding uniform
561 const struct fp_prec_t
563 reg2val_32
, round_32
, val2reg_32
566 /* Convert a 64-bit double-precision FP value in the target platform
567 format to a sim_fpu value. */
569 reg2val_64 (const void *reg
, sim_fpu
*val
)
571 FD2FPU (*(dword
*)reg
, *val
);
574 /* Round the given sim_fpu value to double precision, following the
575 target platform rounding and denormalization conventions. On
576 AM33/2.0, round_near is the only rounding mode. */
578 round_64 (sim_fpu
*val
)
580 return sim_fpu_round_64 (val
, sim_fpu_round_near
, sim_fpu_denorm_zero
);
583 /* Convert a sim_fpu value to the 64-bit double-precision target
586 val2reg_64 (const sim_fpu
*val
, void *reg
)
588 FPU2FD (*val
, *(dword
*)reg
);
591 /* Define the 64-bit single-precision conversion and rounding uniform
593 const struct fp_prec_t
595 reg2val_64
, round_64
, val2reg_64
598 /* Define shortcuts to the uniform interface operations. */
599 #define REG2VAL(reg,val) (*ops->reg2val) (reg,val)
600 #define ROUND(val) (*ops->round) (val)
601 #define VAL2REG(val,reg) (*ops->val2reg) (val,reg)
603 /* Check whether overflow, underflow or inexact exceptions should be
606 fpu_status_ok (sim_fpu_status stat
)
608 if ((stat
& sim_fpu_status_overflow
)
611 else if ((stat
& (sim_fpu_status_underflow
| sim_fpu_status_denorm
))
614 else if ((stat
& (sim_fpu_status_inexact
| sim_fpu_status_rounded
))
617 else if (stat
& ~ (sim_fpu_status_overflow
618 | sim_fpu_status_underflow
619 | sim_fpu_status_denorm
620 | sim_fpu_status_inexact
621 | sim_fpu_status_rounded
))
628 /* Implement a 32/64 bit reciprocal square root, signaling FP
629 exceptions when appropriate. */
631 fpu_rsqrt (SIM_DESC sd
, sim_cpu
*cpu
, sim_cia cia
,
632 const void *reg_in
, void *reg_out
, const struct fp_prec_t
*ops
)
634 sim_fpu in
, med
, out
;
636 REG2VAL (reg_in
, &in
);
639 switch (sim_fpu_is (&in
))
641 case SIM_FPU_IS_SNAN
:
642 case SIM_FPU_IS_NNUMBER
:
643 case SIM_FPU_IS_NINF
:
647 VAL2REG (&sim_fpu_qnan
, reg_out
);
650 case SIM_FPU_IS_QNAN
:
651 VAL2REG (&sim_fpu_qnan
, reg_out
);
654 case SIM_FPU_IS_PINF
:
655 VAL2REG (&sim_fpu_zero
, reg_out
);
658 case SIM_FPU_IS_PNUMBER
:
660 /* Since we don't have a function to compute rsqrt directly,
662 sim_fpu_status stat
= 0;
663 stat
|= sim_fpu_sqrt (&med
, &in
);
664 stat
|= sim_fpu_inv (&out
, &med
);
665 stat
|= ROUND (&out
);
666 if (fpu_status_ok (stat
))
667 VAL2REG (&out
, reg_out
);
671 case SIM_FPU_IS_NZERO
:
672 case SIM_FPU_IS_PZERO
:
677 /* Generate an INF with the same sign. */
678 sim_fpu_inv (&out
, &in
);
679 VAL2REG (&out
, reg_out
);
687 fpu_check_signal_exception (sd
, cpu
, cia
);
695 case SIM_FPU_IS_SNAN
:
696 case SIM_FPU_IS_QNAN
:
699 case SIM_FPU_IS_NINF
:
700 case SIM_FPU_IS_NNUMBER
:
701 case SIM_FPU_IS_NDENORM
:
704 case SIM_FPU_IS_PINF
:
705 case SIM_FPU_IS_PNUMBER
:
706 case SIM_FPU_IS_PDENORM
:
709 case SIM_FPU_IS_NZERO
:
710 case SIM_FPU_IS_PZERO
:
718 /* Implement a 32/64 bit FP compare, setting the FPCR status and/or
719 exception bits as specified. */
721 fpu_cmp (SIM_DESC sd
, sim_cpu
*cpu
, sim_cia cia
,
722 const void *reg_in1
, const void *reg_in2
,
723 const struct fp_prec_t
*ops
)
727 REG2VAL (reg_in1
, &m
);
728 REG2VAL (reg_in2
, &n
);
733 if (sim_fpu_is_snan (&m
) || sim_fpu_is_snan (&n
))
741 FPCR
|= cmp2fcc (sim_fpu_cmp (&m
, &n
));
743 fpu_check_signal_exception (sd
, cpu
, cia
);
746 /* Implement a 32/64 bit FP add, setting FP exception bits when
749 fpu_add (SIM_DESC sd
, sim_cpu
*cpu
, sim_cia cia
,
750 const void *reg_in1
, const void *reg_in2
,
751 void *reg_out
, const struct fp_prec_t
*ops
)
755 REG2VAL (reg_in1
, &m
);
756 REG2VAL (reg_in2
, &n
);
760 if (sim_fpu_is_snan (&m
) || sim_fpu_is_snan (&n
)
761 || (sim_fpu_is (&m
) == SIM_FPU_IS_PINF
762 && sim_fpu_is (&n
) == SIM_FPU_IS_NINF
)
763 || (sim_fpu_is (&m
) == SIM_FPU_IS_NINF
764 && sim_fpu_is (&n
) == SIM_FPU_IS_PINF
))
769 VAL2REG (&sim_fpu_qnan
, reg_out
);
773 sim_fpu_status stat
= sim_fpu_add (&r
, &m
, &n
);
775 if (fpu_status_ok (stat
))
776 VAL2REG (&r
, reg_out
);
779 fpu_check_signal_exception (sd
, cpu
, cia
);
782 /* Implement a 32/64 bit FP sub, setting FP exception bits when
785 fpu_sub (SIM_DESC sd
, sim_cpu
*cpu
, sim_cia cia
,
786 const void *reg_in1
, const void *reg_in2
,
787 void *reg_out
, const struct fp_prec_t
*ops
)
791 REG2VAL (reg_in1
, &m
);
792 REG2VAL (reg_in2
, &n
);
796 if (sim_fpu_is_snan (&m
) || sim_fpu_is_snan (&n
)
797 || (sim_fpu_is (&m
) == SIM_FPU_IS_PINF
798 && sim_fpu_is (&n
) == SIM_FPU_IS_PINF
)
799 || (sim_fpu_is (&m
) == SIM_FPU_IS_NINF
800 && sim_fpu_is (&n
) == SIM_FPU_IS_NINF
))
805 VAL2REG (&sim_fpu_qnan
, reg_out
);
809 sim_fpu_status stat
= sim_fpu_sub (&r
, &m
, &n
);
811 if (fpu_status_ok (stat
))
812 VAL2REG (&r
, reg_out
);
815 fpu_check_signal_exception (sd
, cpu
, cia
);
818 /* Implement a 32/64 bit FP mul, setting FP exception bits when
821 fpu_mul (SIM_DESC sd
, sim_cpu
*cpu
, sim_cia cia
,
822 const void *reg_in1
, const void *reg_in2
,
823 void *reg_out
, const struct fp_prec_t
*ops
)
827 REG2VAL (reg_in1
, &m
);
828 REG2VAL (reg_in2
, &n
);
832 if (sim_fpu_is_snan (&m
) || sim_fpu_is_snan (&n
)
833 || (sim_fpu_is_infinity (&m
) && sim_fpu_is_zero (&n
))
834 || (sim_fpu_is_zero (&m
) && sim_fpu_is_infinity (&n
)))
839 VAL2REG (&sim_fpu_qnan
, reg_out
);
843 sim_fpu_status stat
= sim_fpu_mul (&r
, &m
, &n
);
845 if (fpu_status_ok (stat
))
846 VAL2REG (&r
, reg_out
);
849 fpu_check_signal_exception (sd
, cpu
, cia
);
852 /* Implement a 32/64 bit FP div, setting FP exception bits when
855 fpu_div (SIM_DESC sd
, sim_cpu
*cpu
, sim_cia cia
,
856 const void *reg_in1
, const void *reg_in2
,
857 void *reg_out
, const struct fp_prec_t
*ops
)
861 REG2VAL (reg_in1
, &m
);
862 REG2VAL (reg_in2
, &n
);
866 if (sim_fpu_is_snan (&m
) || sim_fpu_is_snan (&n
)
867 || (sim_fpu_is_infinity (&m
) && sim_fpu_is_infinity (&n
))
868 || (sim_fpu_is_zero (&m
) && sim_fpu_is_zero (&n
)))
873 VAL2REG (&sim_fpu_qnan
, reg_out
);
875 else if (sim_fpu_is_number (&m
) && sim_fpu_is_zero (&n
)
880 sim_fpu_status stat
= sim_fpu_div (&r
, &m
, &n
);
882 if (fpu_status_ok (stat
))
883 VAL2REG (&r
, reg_out
);
886 fpu_check_signal_exception (sd
, cpu
, cia
);
889 /* Implement a 32/64 bit FP madd, setting FP exception bits when
892 fpu_fmadd (SIM_DESC sd
, sim_cpu
*cpu
, sim_cia cia
,
893 const void *reg_in1
, const void *reg_in2
, const void *reg_in3
,
894 void *reg_out
, const struct fp_prec_t
*ops
)
896 sim_fpu m1
, m2
, m
, n
, r
;
898 REG2VAL (reg_in1
, &m1
);
899 REG2VAL (reg_in2
, &m2
);
900 REG2VAL (reg_in3
, &n
);
905 if (sim_fpu_is_snan (&m1
) || sim_fpu_is_snan (&m2
) || sim_fpu_is_snan (&n
)
906 || (sim_fpu_is_infinity (&m1
) && sim_fpu_is_zero (&m2
))
907 || (sim_fpu_is_zero (&m1
) && sim_fpu_is_infinity (&m2
)))
913 VAL2REG (&sim_fpu_qnan
, reg_out
);
917 sim_fpu_status stat
= sim_fpu_mul (&m
, &m1
, &m2
);
919 if (sim_fpu_is_infinity (&m
) && sim_fpu_is_infinity (&n
)
920 && sim_fpu_sign (&m
) != sim_fpu_sign (&n
))
921 goto invalid_operands
;
923 stat
|= sim_fpu_add (&r
, &m
, &n
);
925 if (fpu_status_ok (stat
))
926 VAL2REG (&r
, reg_out
);
929 fpu_check_signal_exception (sd
, cpu
, cia
);
932 /* Implement a 32/64 bit FP msub, setting FP exception bits when
935 fpu_fmsub (SIM_DESC sd
, sim_cpu
*cpu
, sim_cia cia
,
936 const void *reg_in1
, const void *reg_in2
, const void *reg_in3
,
937 void *reg_out
, const struct fp_prec_t
*ops
)
939 sim_fpu m1
, m2
, m
, n
, r
;
941 REG2VAL (reg_in1
, &m1
);
942 REG2VAL (reg_in2
, &m2
);
943 REG2VAL (reg_in3
, &n
);
948 if (sim_fpu_is_snan (&m1
) || sim_fpu_is_snan (&m2
) || sim_fpu_is_snan (&n
)
949 || (sim_fpu_is_infinity (&m1
) && sim_fpu_is_zero (&m2
))
950 || (sim_fpu_is_zero (&m1
) && sim_fpu_is_infinity (&m2
)))
956 VAL2REG (&sim_fpu_qnan
, reg_out
);
960 sim_fpu_status stat
= sim_fpu_mul (&m
, &m1
, &m2
);
962 if (sim_fpu_is_infinity (&m
) && sim_fpu_is_infinity (&n
)
963 && sim_fpu_sign (&m
) == sim_fpu_sign (&n
))
964 goto invalid_operands
;
966 stat
|= sim_fpu_sub (&r
, &m
, &n
);
968 if (fpu_status_ok (stat
))
969 VAL2REG (&r
, reg_out
);
972 fpu_check_signal_exception (sd
, cpu
, cia
);
975 /* Implement a 32/64 bit FP nmadd, setting FP exception bits when
978 fpu_fnmadd (SIM_DESC sd
, sim_cpu
*cpu
, sim_cia cia
,
979 const void *reg_in1
, const void *reg_in2
, const void *reg_in3
,
980 void *reg_out
, const struct fp_prec_t
*ops
)
982 sim_fpu m1
, m2
, m
, mm
, n
, r
;
984 REG2VAL (reg_in1
, &m1
);
985 REG2VAL (reg_in2
, &m2
);
986 REG2VAL (reg_in3
, &n
);
991 if (sim_fpu_is_snan (&m1
) || sim_fpu_is_snan (&m2
) || sim_fpu_is_snan (&n
)
992 || (sim_fpu_is_infinity (&m1
) && sim_fpu_is_zero (&m2
))
993 || (sim_fpu_is_zero (&m1
) && sim_fpu_is_infinity (&m2
)))
999 VAL2REG (&sim_fpu_qnan
, reg_out
);
1003 sim_fpu_status stat
= sim_fpu_mul (&m
, &m1
, &m2
);
1005 if (sim_fpu_is_infinity (&m
) && sim_fpu_is_infinity (&n
)
1006 && sim_fpu_sign (&m
) == sim_fpu_sign (&n
))
1007 goto invalid_operands
;
1009 stat
|= sim_fpu_neg (&mm
, &m
);
1010 stat
|= sim_fpu_add (&r
, &mm
, &n
);
1012 if (fpu_status_ok (stat
))
1013 VAL2REG (&r
, reg_out
);
1016 fpu_check_signal_exception (sd
, cpu
, cia
);
1019 /* Implement a 32/64 bit FP nmsub, setting FP exception bits when
1022 fpu_fnmsub (SIM_DESC sd
, sim_cpu
*cpu
, sim_cia cia
,
1023 const void *reg_in1
, const void *reg_in2
, const void *reg_in3
,
1024 void *reg_out
, const struct fp_prec_t
*ops
)
1026 sim_fpu m1
, m2
, m
, mm
, n
, r
;
1028 REG2VAL (reg_in1
, &m1
);
1029 REG2VAL (reg_in2
, &m2
);
1030 REG2VAL (reg_in3
, &n
);
1035 if (sim_fpu_is_snan (&m1
) || sim_fpu_is_snan (&m2
) || sim_fpu_is_snan (&n
)
1036 || (sim_fpu_is_infinity (&m1
) && sim_fpu_is_zero (&m2
))
1037 || (sim_fpu_is_zero (&m1
) && sim_fpu_is_infinity (&m2
)))
1043 VAL2REG (&sim_fpu_qnan
, reg_out
);
1047 sim_fpu_status stat
= sim_fpu_mul (&m
, &m1
, &m2
);
1049 if (sim_fpu_is_infinity (&m
) && sim_fpu_is_infinity (&n
)
1050 && sim_fpu_sign (&m
) != sim_fpu_sign (&n
))
1051 goto invalid_operands
;
1053 stat
|= sim_fpu_neg (&mm
, &m
);
1054 stat
|= sim_fpu_sub (&r
, &mm
, &n
);
1056 if (fpu_status_ok (stat
))
1057 VAL2REG (&r
, reg_out
);
1060 fpu_check_signal_exception (sd
, cpu
, cia
);