5 #include "sim-options.h"
9 #include "sim-assert.h"
35 host_callback
*mn10300_callback
;
40 /* simulation target board. NULL=default configuration */
41 static char* board
= NULL
;
43 static DECLARE_OPTION_HANDLER (mn10300_option_handler
);
46 OPTION_BOARD
= OPTION_START
,
50 mn10300_option_handler (SIM_DESC sd
,
63 board
= zalloc(strlen(arg
) + 1);
73 static const OPTION mn10300_options
[] =
75 #define BOARD_AM32 "stdeval1"
76 { {"board", required_argument
, NULL
, OPTION_BOARD
},
77 '\0', "none" /* rely on compile-time string concatenation for other options */
79 , "Customize simulation for a particular board.", mn10300_option_handler
},
81 { {NULL
, no_argument
, NULL
, 0}, '\0', NULL
, NULL
, NULL
}
84 /* For compatibility */
87 /* These default values correspond to expected usage for the chip. */
90 sim_open (SIM_OPEN_KIND kind
,
95 SIM_DESC sd
= sim_state_alloc (kind
, cb
);
96 mn10300_callback
= cb
;
98 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
100 /* for compatibility */
103 /* FIXME: should be better way of setting up interrupts. For
104 moment, only support watchpoints causing a breakpoint (gdb
106 STATE_WATCHPOINTS (sd
)->pc
= &(PC
);
107 STATE_WATCHPOINTS (sd
)->sizeof_pc
= sizeof (PC
);
108 STATE_WATCHPOINTS (sd
)->interrupt_handler
= NULL
;
109 STATE_WATCHPOINTS (sd
)->interrupt_names
= NULL
;
111 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
113 sim_add_option_table (sd
, NULL
, mn10300_options
);
115 /* Allocate core managed memory */
116 sim_do_command (sd
, "memory region 0,0x100000");
117 sim_do_command (sd
, "memory region 0x40000000,0x200000");
119 /* getopt will print the error message so we just have to exit if this fails.
120 FIXME: Hmmm... in the case of gdb we need getopt to call
122 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
124 /* Uninstall the modules to avoid memory leaks,
125 file descriptor leaks, etc. */
126 sim_module_uninstall (sd
);
131 && (strcmp(board
, BOARD_AM32
) == 0 ) )
134 STATE_ENVIRONMENT (sd
) = OPERATING_ENVIRONMENT
;
136 sim_do_command (sd
, "memory region 0x44000000,0x40000");
137 sim_do_command (sd
, "memory region 0x48000000,0x400000");
139 /* device support for mn1030002 */
140 /* interrupt controller */
142 sim_hw_parse (sd
, "/mn103int@0x34000100/reg 0x34000100 0x7C 0x34000200 0x8 0x34000280 0x8");
144 /* DEBUG: NMI input's */
145 sim_hw_parse (sd
, "/glue@0x30000000/reg 0x30000000 12");
146 sim_hw_parse (sd
, "/glue@0x30000000 > int0 nmirq /mn103int");
147 sim_hw_parse (sd
, "/glue@0x30000000 > int1 watchdog /mn103int");
148 sim_hw_parse (sd
, "/glue@0x30000000 > int2 syserr /mn103int");
150 /* DEBUG: ACK input */
151 sim_hw_parse (sd
, "/glue@0x30002000/reg 0x30002000 4");
152 sim_hw_parse (sd
, "/glue@0x30002000 > int ack /mn103int");
154 /* DEBUG: LEVEL output */
155 sim_hw_parse (sd
, "/glue@0x30004000/reg 0x30004000 8");
156 sim_hw_parse (sd
, "/mn103int > nmi int0 /glue@0x30004000");
157 sim_hw_parse (sd
, "/mn103int > level int1 /glue@0x30004000");
159 /* DEBUG: A bunch of interrupt inputs */
160 sim_hw_parse (sd
, "/glue@0x30006000/reg 0x30006000 32");
161 sim_hw_parse (sd
, "/glue@0x30006000 > int0 irq-0 /mn103int");
162 sim_hw_parse (sd
, "/glue@0x30006000 > int1 irq-1 /mn103int");
163 sim_hw_parse (sd
, "/glue@0x30006000 > int2 irq-2 /mn103int");
164 sim_hw_parse (sd
, "/glue@0x30006000 > int3 irq-3 /mn103int");
165 sim_hw_parse (sd
, "/glue@0x30006000 > int4 irq-4 /mn103int");
166 sim_hw_parse (sd
, "/glue@0x30006000 > int5 irq-5 /mn103int");
167 sim_hw_parse (sd
, "/glue@0x30006000 > int6 irq-6 /mn103int");
168 sim_hw_parse (sd
, "/glue@0x30006000 > int7 irq-7 /mn103int");
170 /* processor interrupt device */
173 sim_hw_parse (sd
, "/mn103cpu@0x20000000");
174 sim_hw_parse (sd
, "/mn103cpu@0x20000000/reg 0x20000000 0x42");
176 /* DEBUG: ACK output wired upto a glue device */
177 sim_hw_parse (sd
, "/glue@0x20002000");
178 sim_hw_parse (sd
, "/glue@0x20002000/reg 0x20002000 4");
179 sim_hw_parse (sd
, "/mn103cpu > ack int0 /glue@0x20002000");
181 /* DEBUG: RESET/NMI/LEVEL wired up to a glue device */
182 sim_hw_parse (sd
, "/glue@0x20004000");
183 sim_hw_parse (sd
, "/glue@0x20004000/reg 0x20004000 12");
184 sim_hw_parse (sd
, "/glue@0x20004000 > int0 reset /mn103cpu");
185 sim_hw_parse (sd
, "/glue@0x20004000 > int1 nmi /mn103cpu");
186 sim_hw_parse (sd
, "/glue@0x20004000 > int2 level /mn103cpu");
188 /* REAL: The processor wired up to the real interrupt controller */
189 sim_hw_parse (sd
, "/mn103cpu > ack ack /mn103int");
190 sim_hw_parse (sd
, "/mn103int > level level /mn103cpu");
191 sim_hw_parse (sd
, "/mn103int > nmi nmi /mn103cpu");
197 sim_hw_parse (sd
, "/pal@0x31000000");
198 sim_hw_parse (sd
, "/pal@0x31000000/reg 0x31000000 64");
199 sim_hw_parse (sd
, "/pal@0x31000000/poll? true");
201 /* DEBUG: PAL wired up to a glue device */
202 sim_hw_parse (sd
, "/glue@0x31002000");
203 sim_hw_parse (sd
, "/glue@0x31002000/reg 0x31002000 16");
204 sim_hw_parse (sd
, "/pal@0x31000000 > countdown int0 /glue@0x31002000");
205 sim_hw_parse (sd
, "/pal@0x31000000 > timer int1 /glue@0x31002000");
206 sim_hw_parse (sd
, "/pal@0x31000000 > int int2 /glue@0x31002000");
207 sim_hw_parse (sd
, "/glue@0x31002000 > int0 int3 /glue@0x31002000");
208 sim_hw_parse (sd
, "/glue@0x31002000 > int1 int3 /glue@0x31002000");
209 sim_hw_parse (sd
, "/glue@0x31002000 > int2 int3 /glue@0x31002000");
211 /* REAL: The PAL wired up to the real interrupt controller */
212 sim_hw_parse (sd
, "/pal@0x31000000 > countdown irq-0 /mn103int");
213 sim_hw_parse (sd
, "/pal@0x31000000 > timer irq-1 /mn103int");
214 sim_hw_parse (sd
, "/pal@0x31000000 > int irq-2 /mn103int");
216 /* 8 and 16 bit timers */
217 sim_hw_parse (sd
, "/mn103tim@0x34001000/reg 0x34001000 36 0x34001080 100 0x34004000 16");
219 /* Hook timer interrupts up to interrupt controller */
220 sim_hw_parse (sd
, "/mn103tim > timer-0-underflow timer-0-underflow /mn103int");
221 sim_hw_parse (sd
, "/mn103tim > timer-1-underflow timer-1-underflow /mn103int");
222 sim_hw_parse (sd
, "/mn103tim > timer-2-underflow timer-2-underflow /mn103int");
223 sim_hw_parse (sd
, "/mn103tim > timer-3-underflow timer-3-underflow /mn103int");
224 sim_hw_parse (sd
, "/mn103tim > timer-4-underflow timer-4-underflow /mn103int");
225 sim_hw_parse (sd
, "/mn103tim > timer-5-underflow timer-5-underflow /mn103int");
226 sim_hw_parse (sd
, "/mn103tim > timer-6-underflow timer-6-underflow /mn103int");
227 sim_hw_parse (sd
, "/mn103tim > timer-6-compare-a timer-6-compare-a /mn103int");
228 sim_hw_parse (sd
, "/mn103tim > timer-6-compare-b timer-6-compare-b /mn103int");
231 /* Serial devices 0,1,2 */
232 sim_hw_parse (sd
, "/mn103ser@0x34000800/reg 0x34000800 48");
233 sim_hw_parse (sd
, "/mn103ser@0x34000800/poll? true");
235 /* Hook serial interrupts up to interrupt controller */
236 sim_hw_parse (sd
, "/mn103ser > serial-0-receive serial-0-receive /mn103int");
237 sim_hw_parse (sd
, "/mn103ser > serial-0-transmit serial-0-transmit /mn103int");
238 sim_hw_parse (sd
, "/mn103ser > serial-1-receive serial-1-receive /mn103int");
239 sim_hw_parse (sd
, "/mn103ser > serial-1-transmit serial-1-transmit /mn103int");
240 sim_hw_parse (sd
, "/mn103ser > serial-2-receive serial-2-receive /mn103int");
241 sim_hw_parse (sd
, "/mn103ser > serial-2-transmit serial-2-transmit /mn103int");
243 sim_hw_parse (sd
, "/mn103iop@0x36008000/reg 0x36008000 8 0x36008020 8 0x36008040 0xc 0x36008060 8 0x36008080 8");
245 /* Memory control registers */
246 sim_do_command (sd
, "memory region 0x32000020,0x30");
247 /* Cache control register */
248 sim_do_command (sd
, "memory region 0x20000070,0x4");
249 /* Cache purge regions */
250 sim_do_command (sd
, "memory region 0x28400000,0x800");
251 sim_do_command (sd
, "memory region 0x28401000,0x800");
253 sim_do_command (sd
, "memory region 0x32000100,0xF");
254 sim_do_command (sd
, "memory region 0x32000200,0xF");
255 sim_do_command (sd
, "memory region 0x32000400,0xF");
256 sim_do_command (sd
, "memory region 0x32000800,0xF");
262 sim_io_eprintf (sd
, "Error: Board `%s' unknown.\n", board
);
269 /* check for/establish the a reference program image */
270 if (sim_analyze_program (sd
,
271 (STATE_PROG_ARGV (sd
) != NULL
272 ? *STATE_PROG_ARGV (sd
)
276 sim_module_uninstall (sd
);
280 /* establish any remaining configuration options */
281 if (sim_config (sd
) != SIM_RC_OK
)
283 sim_module_uninstall (sd
);
287 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
289 /* Uninstall the modules to avoid memory leaks,
290 file descriptor leaks, etc. */
291 sim_module_uninstall (sd
);
296 /* set machine specific configuration */
297 /* STATE_CPU (sd, 0)->psw_mask = (PSW_NP | PSW_EP | PSW_ID | PSW_SAT */
298 /* | PSW_CY | PSW_OV | PSW_S | PSW_Z); */
305 sim_close (SIM_DESC sd
, int quitting
)
307 sim_module_uninstall (sd
);
312 sim_create_inferior (SIM_DESC sd
,
313 struct bfd
*prog_bfd
,
317 memset (&State
, 0, sizeof (State
));
318 if (prog_bfd
!= NULL
) {
319 PC
= bfd_get_start_address (prog_bfd
);
323 CIA_SET (STATE_CPU (sd
, 0), (unsigned64
) PC
);
325 if (STATE_ARCHITECTURE (sd
)->mach
== bfd_mach_am33_2
)
331 /* FIXME These would more efficient to use than load_mem/store_mem,
332 but need to be changed to use the memory map. */
344 return (a
[1] << 8) + (a
[0]);
351 return (a
[3]<<24) + (a
[2]<<16) + (a
[1]<<8) + (a
[0]);
355 put_byte (uint8
*addr
, uint8 data
)
362 put_half (uint8
*addr
, uint16 data
)
366 a
[1] = (data
>> 8) & 0xff;
370 put_word (uint8
*addr
, uint32 data
)
374 a
[1] = (data
>> 8) & 0xff;
375 a
[2] = (data
>> 16) & 0xff;
376 a
[3] = (data
>> 24) & 0xff;
380 sim_fetch_register (SIM_DESC sd
,
382 unsigned char *memory
,
385 put_word (memory
, State
.regs
[rn
]);
390 sim_store_register (SIM_DESC sd
,
392 unsigned char *memory
,
395 State
.regs
[rn
] = get_word (memory
);
400 sim_pc_get (sim_cpu
*cpu
)
406 mn10300_core_signal (SIM_DESC sd
,
412 transfer_type transfer
,
413 sim_core_signals sig
)
415 const char *copy
= (transfer
== read_transfer
? "read" : "write");
416 address_word ip
= CIA_ADDR (cia
);
420 case sim_core_unmapped_signal
:
421 sim_io_eprintf (sd
, "mn10300-core: %d byte %s to unmapped address 0x%lx at 0x%lx\n",
423 (unsigned long) addr
, (unsigned long) ip
);
424 program_interrupt(sd
, cpu
, cia
, SIM_SIGSEGV
);
427 case sim_core_unaligned_signal
:
428 sim_io_eprintf (sd
, "mn10300-core: %d byte %s to unaligned address 0x%lx at 0x%lx\n",
430 (unsigned long) addr
, (unsigned long) ip
);
431 program_interrupt(sd
, cpu
, cia
, SIM_SIGBUS
);
435 sim_engine_abort (sd
, cpu
, cia
,
436 "mn10300_core_signal - internal error - bad switch");
442 program_interrupt (SIM_DESC sd
,
449 static int in_interrupt
= 0;
451 #ifdef SIM_CPU_EXCEPTION_TRIGGER
452 SIM_CPU_EXCEPTION_TRIGGER(sd
,cpu
,cia
);
455 /* avoid infinite recursion */
458 (*mn10300_callback
->printf_filtered
) (mn10300_callback
,
459 "ERROR: recursion in program_interrupt during software exception dispatch.");
464 /* copy NMI handler code from dv-mn103cpu.c */
465 store_word (SP
- 4, CIA_GET (cpu
));
466 store_half (SP
- 8, PSW
);
468 /* Set the SYSEF flag in NMICR by backdoor method. See
469 dv-mn103int.c:write_icr(). This is necessary because
470 software exceptions are not modelled by actually talking to
471 the interrupt controller, so it cannot set its own SYSEF
473 if ((NULL
!= board
) && (strcmp(board
, BOARD_AM32
) == 0))
474 store_byte (0x34000103, 0x04);
479 CIA_SET (cpu
, 0x40000008);
482 sim_engine_halt(sd
, cpu
, NULL
, cia
, sim_stopped
, sig
);
487 mn10300_cpu_exception_trigger(SIM_DESC sd
, sim_cpu
* cpu
, address_word cia
)
491 if(State
.exc_suspended
> 0)
492 sim_io_eprintf(sd
, "Warning, nested exception triggered (%d)\n", State
.exc_suspended
);
495 memcpy(State
.exc_trigger_regs
, State
.regs
, sizeof(State
.exc_trigger_regs
));
496 State
.exc_suspended
= 0;
500 mn10300_cpu_exception_suspend(SIM_DESC sd
, sim_cpu
* cpu
, int exception
)
504 if(State
.exc_suspended
> 0)
505 sim_io_eprintf(sd
, "Warning, nested exception signal (%d then %d)\n",
506 State
.exc_suspended
, exception
);
508 memcpy(State
.exc_suspend_regs
, State
.regs
, sizeof(State
.exc_suspend_regs
));
509 memcpy(State
.regs
, State
.exc_trigger_regs
, sizeof(State
.regs
));
510 CIA_SET (cpu
, PC
); /* copy PC back from new State.regs */
511 State
.exc_suspended
= exception
;
515 mn10300_cpu_exception_resume(SIM_DESC sd
, sim_cpu
* cpu
, int exception
)
519 if(exception
== 0 && State
.exc_suspended
> 0)
521 if(State
.exc_suspended
!= SIGTRAP
) /* warn not for breakpoints */
522 sim_io_eprintf(sd
, "Warning, resuming but ignoring pending exception signal (%d)\n",
523 State
.exc_suspended
);
525 else if(exception
!= 0 && State
.exc_suspended
> 0)
527 if(exception
!= State
.exc_suspended
)
528 sim_io_eprintf(sd
, "Warning, resuming with mismatched exception signal (%d vs %d)\n",
529 State
.exc_suspended
, exception
);
531 memcpy(State
.regs
, State
.exc_suspend_regs
, sizeof(State
.regs
));
532 CIA_SET (cpu
, PC
); /* copy PC back from new State.regs */
534 else if(exception
!= 0 && State
.exc_suspended
== 0)
536 sim_io_eprintf(sd
, "Warning, ignoring spontanous exception signal (%d)\n", exception
);
538 State
.exc_suspended
= 0;
541 /* This is called when an FP instruction is issued when the FP unit is
542 disabled, i.e., the FE bit of PSW is zero. It raises interrupt
545 fpu_disabled_exception (SIM_DESC sd
, sim_cpu
*cpu
, sim_cia cia
)
547 sim_io_eprintf(sd
, "FPU disabled exception\n");
548 program_interrupt (sd
, cpu
, cia
, SIM_SIGFPE
);
551 /* This is called when the FP unit is enabled but one of the
552 unimplemented insns is issued. It raises interrupt code 0x1c8. */
554 fpu_unimp_exception (SIM_DESC sd
, sim_cpu
*cpu
, sim_cia cia
)
556 sim_io_eprintf(sd
, "Unimplemented FPU instruction exception\n");
557 program_interrupt (sd
, cpu
, cia
, SIM_SIGFPE
);
560 /* This is called at the end of any FP insns that may have triggered
561 FP exceptions. If no exception is enabled, it returns immediately.
562 Otherwise, it raises an exception code 0x1d0. */
564 fpu_check_signal_exception (SIM_DESC sd
, sim_cpu
*cpu
, sim_cia cia
)
566 if ((FPCR
& EC_MASK
) == 0)
569 sim_io_eprintf(sd
, "FPU %s%s%s%s%s exception\n",
570 (FPCR
& EC_V
) ? "V" : "",
571 (FPCR
& EC_Z
) ? "Z" : "",
572 (FPCR
& EC_O
) ? "O" : "",
573 (FPCR
& EC_U
) ? "U" : "",
574 (FPCR
& EC_I
) ? "I" : "");
575 program_interrupt (sd
, cpu
, cia
, SIM_SIGFPE
);
578 /* Convert a 32-bit single-precision FP value in the target platform
579 format to a sim_fpu value. */
581 reg2val_32 (const void *reg
, sim_fpu
*val
)
583 FS2FPU (*(reg_t
*)reg
, *val
);
586 /* Round the given sim_fpu value to single precision, following the
587 target platform rounding and denormalization conventions. On
588 AM33/2.0, round_near is the only rounding mode. */
590 round_32 (sim_fpu
*val
)
592 return sim_fpu_round_32 (val
, sim_fpu_round_near
, sim_fpu_denorm_zero
);
595 /* Convert a sim_fpu value to the 32-bit single-precision target
598 val2reg_32 (const sim_fpu
*val
, void *reg
)
600 FPU2FS (*val
, *(reg_t
*)reg
);
603 /* Define the 32-bit single-precision conversion and rounding uniform
605 const struct fp_prec_t
607 reg2val_32
, round_32
, val2reg_32
610 /* Convert a 64-bit double-precision FP value in the target platform
611 format to a sim_fpu value. */
613 reg2val_64 (const void *reg
, sim_fpu
*val
)
615 FD2FPU (*(dword
*)reg
, *val
);
618 /* Round the given sim_fpu value to double precision, following the
619 target platform rounding and denormalization conventions. On
620 AM33/2.0, round_near is the only rounding mode. */
622 round_64 (sim_fpu
*val
)
624 return sim_fpu_round_64 (val
, sim_fpu_round_near
, sim_fpu_denorm_zero
);
627 /* Convert a sim_fpu value to the 64-bit double-precision target
630 val2reg_64 (const sim_fpu
*val
, void *reg
)
632 FPU2FD (*val
, *(dword
*)reg
);
635 /* Define the 64-bit single-precision conversion and rounding uniform
637 const struct fp_prec_t
639 reg2val_64
, round_64
, val2reg_64
642 /* Define shortcuts to the uniform interface operations. */
643 #define REG2VAL(reg,val) (*ops->reg2val) (reg,val)
644 #define ROUND(val) (*ops->round) (val)
645 #define VAL2REG(val,reg) (*ops->val2reg) (val,reg)
647 /* Check whether overflow, underflow or inexact exceptions should be
650 fpu_status_ok (sim_fpu_status stat
)
652 if ((stat
& sim_fpu_status_overflow
)
655 else if ((stat
& (sim_fpu_status_underflow
| sim_fpu_status_denorm
))
658 else if ((stat
& (sim_fpu_status_inexact
| sim_fpu_status_rounded
))
661 else if (stat
& ~ (sim_fpu_status_overflow
662 | sim_fpu_status_underflow
663 | sim_fpu_status_denorm
664 | sim_fpu_status_inexact
665 | sim_fpu_status_rounded
))
672 /* Implement a 32/64 bit reciprocal square root, signaling FP
673 exceptions when appropriate. */
675 fpu_rsqrt (SIM_DESC sd
, sim_cpu
*cpu
, sim_cia cia
,
676 const void *reg_in
, void *reg_out
, const struct fp_prec_t
*ops
)
678 sim_fpu in
, med
, out
;
680 REG2VAL (reg_in
, &in
);
683 switch (sim_fpu_is (&in
))
685 case SIM_FPU_IS_SNAN
:
686 case SIM_FPU_IS_NNUMBER
:
687 case SIM_FPU_IS_NINF
:
691 VAL2REG (&sim_fpu_qnan
, reg_out
);
694 case SIM_FPU_IS_QNAN
:
695 VAL2REG (&sim_fpu_qnan
, reg_out
);
698 case SIM_FPU_IS_PINF
:
699 VAL2REG (&sim_fpu_zero
, reg_out
);
702 case SIM_FPU_IS_PNUMBER
:
704 /* Since we don't have a function to compute rsqrt directly,
706 sim_fpu_status stat
= 0;
707 stat
|= sim_fpu_sqrt (&med
, &in
);
708 stat
|= sim_fpu_inv (&out
, &med
);
709 stat
|= ROUND (&out
);
710 if (fpu_status_ok (stat
))
711 VAL2REG (&out
, reg_out
);
715 case SIM_FPU_IS_NZERO
:
716 case SIM_FPU_IS_PZERO
:
721 /* Generate an INF with the same sign. */
722 sim_fpu_inv (&out
, &in
);
723 VAL2REG (&out
, reg_out
);
731 fpu_check_signal_exception (sd
, cpu
, cia
);
739 case SIM_FPU_IS_SNAN
:
740 case SIM_FPU_IS_QNAN
:
743 case SIM_FPU_IS_NINF
:
744 case SIM_FPU_IS_NNUMBER
:
745 case SIM_FPU_IS_NDENORM
:
748 case SIM_FPU_IS_PINF
:
749 case SIM_FPU_IS_PNUMBER
:
750 case SIM_FPU_IS_PDENORM
:
753 case SIM_FPU_IS_NZERO
:
754 case SIM_FPU_IS_PZERO
:
762 /* Implement a 32/64 bit FP compare, setting the FPCR status and/or
763 exception bits as specified. */
765 fpu_cmp (SIM_DESC sd
, sim_cpu
*cpu
, sim_cia cia
,
766 const void *reg_in1
, const void *reg_in2
,
767 const struct fp_prec_t
*ops
)
771 REG2VAL (reg_in1
, &m
);
772 REG2VAL (reg_in2
, &n
);
777 if (sim_fpu_is_snan (&m
) || sim_fpu_is_snan (&n
))
785 FPCR
|= cmp2fcc (sim_fpu_cmp (&m
, &n
));
787 fpu_check_signal_exception (sd
, cpu
, cia
);
790 /* Implement a 32/64 bit FP add, setting FP exception bits when
793 fpu_add (SIM_DESC sd
, sim_cpu
*cpu
, sim_cia cia
,
794 const void *reg_in1
, const void *reg_in2
,
795 void *reg_out
, const struct fp_prec_t
*ops
)
799 REG2VAL (reg_in1
, &m
);
800 REG2VAL (reg_in2
, &n
);
804 if (sim_fpu_is_snan (&m
) || sim_fpu_is_snan (&n
)
805 || (sim_fpu_is (&m
) == SIM_FPU_IS_PINF
806 && sim_fpu_is (&n
) == SIM_FPU_IS_NINF
)
807 || (sim_fpu_is (&m
) == SIM_FPU_IS_NINF
808 && sim_fpu_is (&n
) == SIM_FPU_IS_PINF
))
813 VAL2REG (&sim_fpu_qnan
, reg_out
);
817 sim_fpu_status stat
= sim_fpu_add (&r
, &m
, &n
);
819 if (fpu_status_ok (stat
))
820 VAL2REG (&r
, reg_out
);
823 fpu_check_signal_exception (sd
, cpu
, cia
);
826 /* Implement a 32/64 bit FP sub, setting FP exception bits when
829 fpu_sub (SIM_DESC sd
, sim_cpu
*cpu
, sim_cia cia
,
830 const void *reg_in1
, const void *reg_in2
,
831 void *reg_out
, const struct fp_prec_t
*ops
)
835 REG2VAL (reg_in1
, &m
);
836 REG2VAL (reg_in2
, &n
);
840 if (sim_fpu_is_snan (&m
) || sim_fpu_is_snan (&n
)
841 || (sim_fpu_is (&m
) == SIM_FPU_IS_PINF
842 && sim_fpu_is (&n
) == SIM_FPU_IS_PINF
)
843 || (sim_fpu_is (&m
) == SIM_FPU_IS_NINF
844 && sim_fpu_is (&n
) == SIM_FPU_IS_NINF
))
849 VAL2REG (&sim_fpu_qnan
, reg_out
);
853 sim_fpu_status stat
= sim_fpu_sub (&r
, &m
, &n
);
855 if (fpu_status_ok (stat
))
856 VAL2REG (&r
, reg_out
);
859 fpu_check_signal_exception (sd
, cpu
, cia
);
862 /* Implement a 32/64 bit FP mul, setting FP exception bits when
865 fpu_mul (SIM_DESC sd
, sim_cpu
*cpu
, sim_cia cia
,
866 const void *reg_in1
, const void *reg_in2
,
867 void *reg_out
, const struct fp_prec_t
*ops
)
871 REG2VAL (reg_in1
, &m
);
872 REG2VAL (reg_in2
, &n
);
876 if (sim_fpu_is_snan (&m
) || sim_fpu_is_snan (&n
)
877 || (sim_fpu_is_infinity (&m
) && sim_fpu_is_zero (&n
))
878 || (sim_fpu_is_zero (&m
) && sim_fpu_is_infinity (&n
)))
883 VAL2REG (&sim_fpu_qnan
, reg_out
);
887 sim_fpu_status stat
= sim_fpu_mul (&r
, &m
, &n
);
889 if (fpu_status_ok (stat
))
890 VAL2REG (&r
, reg_out
);
893 fpu_check_signal_exception (sd
, cpu
, cia
);
896 /* Implement a 32/64 bit FP div, setting FP exception bits when
899 fpu_div (SIM_DESC sd
, sim_cpu
*cpu
, sim_cia cia
,
900 const void *reg_in1
, const void *reg_in2
,
901 void *reg_out
, const struct fp_prec_t
*ops
)
905 REG2VAL (reg_in1
, &m
);
906 REG2VAL (reg_in2
, &n
);
910 if (sim_fpu_is_snan (&m
) || sim_fpu_is_snan (&n
)
911 || (sim_fpu_is_infinity (&m
) && sim_fpu_is_infinity (&n
))
912 || (sim_fpu_is_zero (&m
) && sim_fpu_is_zero (&n
)))
917 VAL2REG (&sim_fpu_qnan
, reg_out
);
919 else if (sim_fpu_is_number (&m
) && sim_fpu_is_zero (&n
)
924 sim_fpu_status stat
= sim_fpu_div (&r
, &m
, &n
);
926 if (fpu_status_ok (stat
))
927 VAL2REG (&r
, reg_out
);
930 fpu_check_signal_exception (sd
, cpu
, cia
);
933 /* Implement a 32/64 bit FP madd, setting FP exception bits when
936 fpu_fmadd (SIM_DESC sd
, sim_cpu
*cpu
, sim_cia cia
,
937 const void *reg_in1
, const void *reg_in2
, const void *reg_in3
,
938 void *reg_out
, const struct fp_prec_t
*ops
)
940 sim_fpu m1
, m2
, m
, n
, r
;
942 REG2VAL (reg_in1
, &m1
);
943 REG2VAL (reg_in2
, &m2
);
944 REG2VAL (reg_in3
, &n
);
949 if (sim_fpu_is_snan (&m1
) || sim_fpu_is_snan (&m2
) || sim_fpu_is_snan (&n
)
950 || (sim_fpu_is_infinity (&m1
) && sim_fpu_is_zero (&m2
))
951 || (sim_fpu_is_zero (&m1
) && sim_fpu_is_infinity (&m2
)))
957 VAL2REG (&sim_fpu_qnan
, reg_out
);
961 sim_fpu_status stat
= sim_fpu_mul (&m
, &m1
, &m2
);
963 if (sim_fpu_is_infinity (&m
) && sim_fpu_is_infinity (&n
)
964 && sim_fpu_sign (&m
) != sim_fpu_sign (&n
))
965 goto invalid_operands
;
967 stat
|= sim_fpu_add (&r
, &m
, &n
);
969 if (fpu_status_ok (stat
))
970 VAL2REG (&r
, reg_out
);
973 fpu_check_signal_exception (sd
, cpu
, cia
);
976 /* Implement a 32/64 bit FP msub, setting FP exception bits when
979 fpu_fmsub (SIM_DESC sd
, sim_cpu
*cpu
, sim_cia cia
,
980 const void *reg_in1
, const void *reg_in2
, const void *reg_in3
,
981 void *reg_out
, const struct fp_prec_t
*ops
)
983 sim_fpu m1
, m2
, m
, n
, r
;
985 REG2VAL (reg_in1
, &m1
);
986 REG2VAL (reg_in2
, &m2
);
987 REG2VAL (reg_in3
, &n
);
992 if (sim_fpu_is_snan (&m1
) || sim_fpu_is_snan (&m2
) || sim_fpu_is_snan (&n
)
993 || (sim_fpu_is_infinity (&m1
) && sim_fpu_is_zero (&m2
))
994 || (sim_fpu_is_zero (&m1
) && sim_fpu_is_infinity (&m2
)))
1000 VAL2REG (&sim_fpu_qnan
, reg_out
);
1004 sim_fpu_status stat
= sim_fpu_mul (&m
, &m1
, &m2
);
1006 if (sim_fpu_is_infinity (&m
) && sim_fpu_is_infinity (&n
)
1007 && sim_fpu_sign (&m
) == sim_fpu_sign (&n
))
1008 goto invalid_operands
;
1010 stat
|= sim_fpu_sub (&r
, &m
, &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 nmadd, setting FP exception bits when
1022 fpu_fnmadd (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_add (&r
, &mm
, &n
);
1056 if (fpu_status_ok (stat
))
1057 VAL2REG (&r
, reg_out
);
1060 fpu_check_signal_exception (sd
, cpu
, cia
);
1063 /* Implement a 32/64 bit FP nmsub, setting FP exception bits when
1066 fpu_fnmsub (SIM_DESC sd
, sim_cpu
*cpu
, sim_cia cia
,
1067 const void *reg_in1
, const void *reg_in2
, const void *reg_in3
,
1068 void *reg_out
, const struct fp_prec_t
*ops
)
1070 sim_fpu m1
, m2
, m
, mm
, n
, r
;
1072 REG2VAL (reg_in1
, &m1
);
1073 REG2VAL (reg_in2
, &m2
);
1074 REG2VAL (reg_in3
, &n
);
1079 if (sim_fpu_is_snan (&m1
) || sim_fpu_is_snan (&m2
) || sim_fpu_is_snan (&n
)
1080 || (sim_fpu_is_infinity (&m1
) && sim_fpu_is_zero (&m2
))
1081 || (sim_fpu_is_zero (&m1
) && sim_fpu_is_infinity (&m2
)))
1087 VAL2REG (&sim_fpu_qnan
, reg_out
);
1091 sim_fpu_status stat
= sim_fpu_mul (&m
, &m1
, &m2
);
1093 if (sim_fpu_is_infinity (&m
) && sim_fpu_is_infinity (&n
)
1094 && sim_fpu_sign (&m
) != sim_fpu_sign (&n
))
1095 goto invalid_operands
;
1097 stat
|= sim_fpu_neg (&mm
, &m
);
1098 stat
|= sim_fpu_sub (&r
, &mm
, &n
);
1100 if (fpu_status_ok (stat
))
1101 VAL2REG (&r
, reg_out
);
1104 fpu_check_signal_exception (sd
, cpu
, cia
);