3d663697380fc499620cc0ac4624c4fbe67cb90c
4 #include "remote-sim.h"
8 #define IMEM_SIZE 18 /* D10V instruction memory size is 18 bits */
9 #define DMEM_SIZE 16 /* Data memory is 64K (but only 32K internal RAM) */
10 #define UMEM_SIZE 17 /* each unified memory region is 17 bits */
12 enum _leftright
{ LEFT_FIRST
, RIGHT_FIRST
};
15 host_callback
*d10v_callback
;
16 unsigned long ins_type_counters
[ (int)INS_MAX
];
20 static long hash
PARAMS ((long insn
, int format
));
21 static struct hash_entry
*lookup_hash
PARAMS ((uint32 ins
, int size
));
22 static void get_operands
PARAMS ((struct simops
*s
, uint32 ins
));
23 static void do_long
PARAMS ((uint32 ins
));
24 static void do_2_short
PARAMS ((uint16 ins1
, uint16 ins2
, enum _leftright leftright
));
25 static void do_parallel
PARAMS ((uint16 ins1
, uint16 ins2
));
26 static char *add_commas
PARAMS ((char *buf
, int sizeof_buf
, unsigned long value
));
27 extern void sim_size
PARAMS ((int power
));
28 static void init_system
PARAMS ((void));
29 extern int sim_write
PARAMS ((SIM_ADDR addr
, unsigned char *buffer
, int size
));
30 extern void sim_open
PARAMS ((char *args
));
31 extern void sim_close
PARAMS ((int quitting
));
32 extern void sim_set_profile
PARAMS ((int n
));
33 extern void sim_set_profile_size
PARAMS ((int n
));
34 extern void sim_resume
PARAMS ((int step
, int siggnal
));
35 extern void sim_info
PARAMS ((int verbose
));
36 extern void sim_create_inferior
PARAMS ((SIM_ADDR start_address
, char **argv
, char **env
));
37 extern void sim_kill
PARAMS ((void));
38 extern void sim_set_callbacks
PARAMS ((host_callback
*p
));
39 extern void sim_stop_reason
PARAMS ((enum sim_stop
*reason
, int *sigrc
));
40 extern void sim_fetch_register
PARAMS ((int rn
, unsigned char *memory
));
41 extern void sim_store_register
PARAMS ((int rn
, unsigned char *memory
));
42 extern int sim_read
PARAMS ((SIM_ADDR addr
, unsigned char *buffer
, int size
));
43 extern void sim_do_command
PARAMS ((char *cmd
));
46 #if defined(__GNUC__) && defined(__OPTIMIZE__)
47 #define INLINE __inline__
56 struct hash_entry
*next
;
62 struct hash_entry hash_table
[MAX_HASH
+1];
69 if (format
& LONG_OPCODE
)
70 return ((insn
& 0x3F000000) >> 24);
72 return((insn
& 0x7E00) >> 9);
75 INLINE
static struct hash_entry
*
76 lookup_hash (ins
, size
)
83 h
= &hash_table
[(ins
& 0x3F000000) >> 24];
85 h
= &hash_table
[(ins
& 0x7E00) >> 9];
87 while ((ins
& h
->mask
) != h
->opcode
)
91 (*d10v_callback
->printf_filtered
) (d10v_callback
, "ERROR looking up hash for %x at PC %x\n",ins
, PC
);
100 get_operands (struct simops
*s
, uint32 ins
)
102 int i
, shift
, bits
, flags
;
104 for (i
=0; i
< s
->numops
; i
++)
106 shift
= s
->operands
[3*i
];
107 bits
= s
->operands
[3*i
+1];
108 flags
= s
->operands
[3*i
+2];
109 mask
= 0x7FFFFFFF >> (31 - bits
);
110 OP
[i
] = (ins
>> shift
) & mask
;
118 struct hash_entry
*h
;
120 if ((d10v_debug
& DEBUG_INSTRUCTION
) != 0)
121 (*d10v_callback
->printf_filtered
) (d10v_callback
, "do_long 0x%x\n", ins
);
123 h
= lookup_hash (ins
, 1);
124 get_operands (h
->ops
, ins
);
125 State
.ins_type
= INS_LONG
;
126 ins_type_counters
[ (int)State
.ins_type
]++;
131 do_2_short (ins1
, ins2
, leftright
)
133 enum _leftright leftright
;
135 struct hash_entry
*h
;
137 enum _ins_type first
, second
;
140 if ((d10v_debug
& DEBUG_INSTRUCTION
) != 0)
141 (*d10v_callback
->printf_filtered
) (d10v_callback
, "do_2_short 0x%x (%s) -> 0x%x\n",
142 ins1
, (leftright
) ? "left" : "right", ins2
);
145 if (leftright
== LEFT_FIRST
)
149 ins_type_counters
[ (int)INS_LEFTRIGHT
]++;
155 ins_type_counters
[ (int)INS_RIGHTLEFT
]++;
158 h
= lookup_hash (ins1
, 0);
159 get_operands (h
->ops
, ins1
);
160 State
.ins_type
= first
;
161 ins_type_counters
[ (int)State
.ins_type
]++;
164 /* If the PC has changed (ie, a jump), don't do the second instruction */
165 if (orig_pc
== PC
&& !State
.exception
)
167 h
= lookup_hash (ins2
, 0);
168 get_operands (h
->ops
, ins2
);
169 State
.ins_type
= second
;
170 ins_type_counters
[ (int)State
.ins_type
]++;
171 ins_type_counters
[ (int)INS_CYCLES
]++;
174 else if (orig_pc
!= PC
&& !State
.exception
)
175 ins_type_counters
[ (int)INS_COND_JUMP
]++;
179 do_parallel (ins1
, ins2
)
182 struct hash_entry
*h1
, *h2
;
184 if ((d10v_debug
& DEBUG_INSTRUCTION
) != 0)
185 (*d10v_callback
->printf_filtered
) (d10v_callback
, "do_parallel 0x%x || 0x%x\n", ins1
, ins2
);
187 ins_type_counters
[ (int)INS_PARALLEL
]++;
188 h1
= lookup_hash (ins1
, 0);
189 h2
= lookup_hash (ins2
, 0);
191 if (h1
->ops
->exec_type
== PARONLY
)
193 get_operands (h1
->ops
, ins1
);
194 State
.ins_type
= INS_LEFT_COND_TEST
;
195 ins_type_counters
[ (int)State
.ins_type
]++;
199 ins_type_counters
[ (int)INS_COND_TRUE
]++;
200 get_operands (h2
->ops
, ins2
);
201 State
.ins_type
= INS_RIGHT_COND_EXE
;
202 ins_type_counters
[ (int)State
.ins_type
]++;
206 ins_type_counters
[ (int)INS_COND_FALSE
]++;
208 else if (h2
->ops
->exec_type
== PARONLY
)
210 get_operands (h2
->ops
, ins2
);
211 State
.ins_type
= INS_RIGHT_COND_TEST
;
212 ins_type_counters
[ (int)State
.ins_type
]++;
216 ins_type_counters
[ (int)INS_COND_TRUE
]++;
217 get_operands (h1
->ops
, ins1
);
218 State
.ins_type
= INS_LEFT_COND_EXE
;
219 ins_type_counters
[ (int)State
.ins_type
]++;
223 ins_type_counters
[ (int)INS_COND_FALSE
]++;
227 get_operands (h1
->ops
, ins1
);
228 State
.ins_type
= INS_LEFT_PARALLEL
;
229 ins_type_counters
[ (int)State
.ins_type
]++;
231 if (!State
.exception
)
233 get_operands (h2
->ops
, ins2
);
234 State
.ins_type
= INS_RIGHT_PARALLEL
;
235 ins_type_counters
[ (int)State
.ins_type
]++;
242 add_commas(buf
, sizeof_buf
, value
)
248 char *endbuf
= buf
+ sizeof_buf
- 1;
258 *--endbuf
= (value
% 10) + '0';
259 } while ((value
/= 10) != 0);
277 free (State
.umem
[i
]);
278 State
.umem
[i
] = NULL
;
285 State
.imem
= (uint8
*)calloc(1,1<<IMEM_SIZE
);
286 State
.dmem
= (uint8
*)calloc(1,1<<DMEM_SIZE
);
288 State
.umem
[i
] = NULL
;
289 State
.umem
[0] = (uint8
*)calloc(1,1<<UMEM_SIZE
);
290 State
.umem
[1] = (uint8
*)calloc(1,1<<UMEM_SIZE
);
291 State
.umem
[2] = (uint8
*)calloc(1,1<<UMEM_SIZE
);
292 State
.umem
[127] = (uint8
*)calloc(1,1<<UMEM_SIZE
);
293 if (!State
.imem
|| !State
.dmem
|| !State
.umem
[0] || !State
.umem
[1] || !State
.umem
[2] || !State
.umem
[127] )
295 (*d10v_callback
->printf_filtered
) (d10v_callback
, "Memory allocation failed.\n");
304 if ((d10v_debug
& DEBUG_MEMSIZE
) != 0)
307 (*d10v_callback
->printf_filtered
) (d10v_callback
,
308 "Allocated %s bytes instruction memory and\n",
309 add_commas (buffer
, sizeof (buffer
), (1UL<<IMEM_SIZE
)));
311 (*d10v_callback
->printf_filtered
) (d10v_callback
, " %s bytes data memory.\n",
312 add_commas (buffer
, sizeof (buffer
), (1UL<<IMEM_SIZE
)));
325 xfer_mem (addr
, buffer
, size
, write
)
327 unsigned char *buffer
;
335 if ((d10v_debug
& DEBUG_INSTRUCTION
) != 0)
338 (*d10v_callback
->printf_filtered
) (d10v_callback
, "sim_write %d bytes to 0x%x\n", size
, addr
);
340 (*d10v_callback
->printf_filtered
) (d10v_callback
, "sim_read %d bytes from 0x%x\n", size
, addr
);
344 /* to access data, we use the following mapping */
345 /* 0x01000000 - 0x0103ffff : instruction memory */
346 /* 0x02000000 - 0x0200ffff : data memory */
347 /* 0x03000000 - 0x03ffffff : unified memory */
349 if ( (addr
& 0x03000000) == 0x03000000)
354 segment
= addr
>> UMEM_SIZE
;
356 if (!State
.umem
[segment
])
357 State
.umem
[segment
] = (uint8
*)calloc(1,1<<UMEM_SIZE
);
358 if (!State
.umem
[segment
])
360 (*d10v_callback
->printf_filtered
) (d10v_callback
, "Memory allocation failed.\n");
364 (*d10v_callback
->printf_filtered
) (d10v_callback
,"Allocated %s bytes unified memory to region %d\n",
365 add_commas (buffer
, sizeof (buffer
), (1UL<<IMEM_SIZE
)), segment
);
367 /* FIXME: need to check size and read/write multiple segments if necessary */
369 memcpy (State
.umem
[segment
]+addr
, buffer
, size
);
371 memcpy (buffer
, State
.umem
[segment
]+addr
, size
);
373 else if ( (addr
& 0x03000000) == 0x02000000)
377 if (size
> (1<<(DMEM_SIZE
-1)))
379 (*d10v_callback
->printf_filtered
) (d10v_callback
, "ERROR: data section is only %d bytes.\n",1<<(DMEM_SIZE
-1));
383 memcpy (State
.dmem
+addr
, buffer
, size
);
385 memcpy (buffer
, State
.dmem
+addr
, size
);
387 else if ( (addr
& 0x03000000) == 0x01000000)
389 /* INSTRUCTION MEMORY */
391 if (size
> (1<<IMEM_SIZE
))
393 (*d10v_callback
->printf_filtered
) (d10v_callback
, "ERROR: inst section is only %d bytes.\n",1<<IMEM_SIZE
);
397 memcpy (State
.imem
+addr
, buffer
, size
);
399 memcpy (buffer
, State
.imem
+addr
, size
);
403 (*d10v_callback
->printf_filtered
) (d10v_callback
, "ERROR: address 0x%x is not in valid range\n",addr
);
404 (*d10v_callback
->printf_filtered
) (d10v_callback
, "Instruction addresses start at 0x01000000\n");
405 (*d10v_callback
->printf_filtered
) (d10v_callback
, "Data addresses start at 0x02000000\n");
406 (*d10v_callback
->printf_filtered
) (d10v_callback
, "Unified addresses start at 0x03000000\n");
417 sim_write (addr
, buffer
, size
)
419 unsigned char *buffer
;
422 return xfer_mem( addr
, buffer
, size
, 1);
426 sim_read (addr
, buffer
, size
)
428 unsigned char *buffer
;
431 return xfer_mem( addr
, buffer
, size
, 0);
440 struct hash_entry
*h
;
441 static int init_p
= 0;
446 if (strcmp (args
, "-t") == 0)
450 (*d10v_callback
->printf_filtered
) (d10v_callback
, "ERROR: unsupported option(s): %s\n",args
);
453 /* put all the opcodes in the hash table */
456 for (s
= Simops
; s
->func
; s
++)
458 h
= &hash_table
[hash(s
->opcode
,s
->format
)];
460 /* go to the last entry in the chain */
466 h
->next
= calloc(1,sizeof(struct hash_entry
));
471 h
->opcode
= s
->opcode
;
488 (*d10v_callback
->printf_filtered
) (d10v_callback
, "sim_set_profile %d\n",n
);
492 sim_set_profile_size (n
)
495 (*d10v_callback
->printf_filtered
) (d10v_callback
, "sim_set_profile_size %d\n",n
);
509 if ( (addr
& 0xfff0) != 0xff00)
510 (*d10v_callback
->printf_filtered
) (d10v_callback
, "Data address %x is in I/O space.\n",addr
);
511 return State
.dmem
+ addr
;
518 /* instruction memory */
519 return (DMAP
& 0xf) * 0x4000 + State
.imem
;
522 /* this is ugly because we allocate unified memory in 128K segments and */
523 /* dmap addresses 16k segments */
524 seg
= (DMAP
& 0x3ff) >> 2;
525 if (State
.umem
[seg
] == NULL
)
527 (*d10v_callback
->printf_filtered
) (d10v_callback
, "ERROR: unified memory region %d unmapped\n", seg
);
530 return State
.umem
[seg
] + (DMAP
& 3) * 0x4000;
533 return State
.dmem
+ addr
;
540 uint32 pc
= ((uint32
)PC
) << 2;
549 return State
.imem
+ pc
;
551 if (State
.umem
[imap
& 0xff] == NULL
)
553 (*d10v_callback
->printf_filtered
) (d10v_callback
, "ERROR: unified memory region %d unmapped\n", imap
& 0xff);
554 State
.exception
= SIGILL
;
558 return State
.umem
[imap
& 0xff] + pc
;
563 sim_resume (step
, siggnal
)
569 /* (*d10v_callback->printf_filtered) (d10v_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC); */
574 inst
= get_longword( pc_addr() );
576 ins_type_counters
[ (int)INS_CYCLES
]++;
577 switch (inst
& 0xC0000000)
580 /* long instruction */
581 do_long (inst
& 0x3FFFFFFF);
585 do_2_short ( inst
& 0x7FFF, (inst
& 0x3FFF8000) >> 15, 0);
589 do_2_short ((inst
& 0x3FFF8000) >> 15, inst
& 0x7FFF, 1);
592 do_parallel ((inst
& 0x3FFF8000) >> 15, inst
& 0x7FFF);
596 if (State
.RP
&& PC
== RPT_E
)
610 while ( !State
.exception
&& !step
);
612 if (step
&& !State
.exception
)
613 State
.exception
= SIGTRAP
;
635 unsigned long left
= ins_type_counters
[ (int)INS_LEFT
] + ins_type_counters
[ (int)INS_LEFT_COND_EXE
];
636 unsigned long left_nops
= ins_type_counters
[ (int)INS_LEFT_NOPS
];
637 unsigned long left_parallel
= ins_type_counters
[ (int)INS_LEFT_PARALLEL
];
638 unsigned long left_cond
= ins_type_counters
[ (int)INS_LEFT_COND_TEST
];
639 unsigned long left_total
= left
+ left_parallel
+ left_cond
+ left_nops
;
641 unsigned long right
= ins_type_counters
[ (int)INS_RIGHT
] + ins_type_counters
[ (int)INS_RIGHT_COND_EXE
];
642 unsigned long right_nops
= ins_type_counters
[ (int)INS_RIGHT_NOPS
];
643 unsigned long right_parallel
= ins_type_counters
[ (int)INS_RIGHT_PARALLEL
];
644 unsigned long right_cond
= ins_type_counters
[ (int)INS_RIGHT_COND_TEST
];
645 unsigned long right_total
= right
+ right_parallel
+ right_cond
+ right_nops
;
647 unsigned long unknown
= ins_type_counters
[ (int)INS_UNKNOWN
];
648 unsigned long ins_long
= ins_type_counters
[ (int)INS_LONG
];
649 unsigned long parallel
= ins_type_counters
[ (int)INS_PARALLEL
];
650 unsigned long leftright
= ins_type_counters
[ (int)INS_LEFTRIGHT
];
651 unsigned long rightleft
= ins_type_counters
[ (int)INS_RIGHTLEFT
];
652 unsigned long cond_true
= ins_type_counters
[ (int)INS_COND_TRUE
];
653 unsigned long cond_false
= ins_type_counters
[ (int)INS_COND_FALSE
];
654 unsigned long cond_jump
= ins_type_counters
[ (int)INS_COND_JUMP
];
655 unsigned long cycles
= ins_type_counters
[ (int)INS_CYCLES
];
656 unsigned long total
= (unknown
+ left_total
+ right_total
+ ins_long
);
658 int size
= strlen (add_commas (buf1
, sizeof (buf1
), total
));
659 int parallel_size
= strlen (add_commas (buf1
, sizeof (buf1
),
660 (left_parallel
> right_parallel
) ? left_parallel
: right_parallel
));
661 int cond_size
= strlen (add_commas (buf1
, sizeof (buf1
), (left_cond
> right_cond
) ? left_cond
: right_cond
));
662 int nop_size
= strlen (add_commas (buf1
, sizeof (buf1
), (left_nops
> right_nops
) ? left_nops
: right_nops
));
663 int normal_size
= strlen (add_commas (buf1
, sizeof (buf1
), (left
> right
) ? left
: right
));
665 (*d10v_callback
->printf_filtered
) (d10v_callback
,
666 "executed %*s left instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
667 size
, add_commas (buf1
, sizeof (buf1
), left_total
),
668 normal_size
, add_commas (buf2
, sizeof (buf2
), left
),
669 parallel_size
, add_commas (buf3
, sizeof (buf3
), left_parallel
),
670 cond_size
, add_commas (buf4
, sizeof (buf4
), left_cond
),
671 nop_size
, add_commas (buf5
, sizeof (buf5
), left_nops
));
673 (*d10v_callback
->printf_filtered
) (d10v_callback
,
674 "executed %*s right instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
675 size
, add_commas (buf1
, sizeof (buf1
), right_total
),
676 normal_size
, add_commas (buf2
, sizeof (buf2
), right
),
677 parallel_size
, add_commas (buf3
, sizeof (buf3
), right_parallel
),
678 cond_size
, add_commas (buf4
, sizeof (buf4
), right_cond
),
679 nop_size
, add_commas (buf5
, sizeof (buf5
), right_nops
));
682 (*d10v_callback
->printf_filtered
) (d10v_callback
,
683 "executed %*s long instruction(s)\n",
684 size
, add_commas (buf1
, sizeof (buf1
), ins_long
));
687 (*d10v_callback
->printf_filtered
) (d10v_callback
,
688 "executed %*s parallel instruction(s)\n",
689 size
, add_commas (buf1
, sizeof (buf1
), parallel
));
692 (*d10v_callback
->printf_filtered
) (d10v_callback
,
693 "executed %*s instruction(s) encoded L->R\n",
694 size
, add_commas (buf1
, sizeof (buf1
), leftright
));
697 (*d10v_callback
->printf_filtered
) (d10v_callback
,
698 "executed %*s instruction(s) encoded R->L\n",
699 size
, add_commas (buf1
, sizeof (buf1
), rightleft
));
702 (*d10v_callback
->printf_filtered
) (d10v_callback
,
703 "executed %*s unknown instruction(s)\n",
704 size
, add_commas (buf1
, sizeof (buf1
), unknown
));
707 (*d10v_callback
->printf_filtered
) (d10v_callback
,
708 "executed %*s instruction(s) due to EXExxx condition being true\n",
709 size
, add_commas (buf1
, sizeof (buf1
), cond_true
));
712 (*d10v_callback
->printf_filtered
) (d10v_callback
,
713 "skipped %*s instruction(s) due to EXExxx condition being false\n",
714 size
, add_commas (buf1
, sizeof (buf1
), cond_false
));
717 (*d10v_callback
->printf_filtered
) (d10v_callback
,
718 "skipped %*s instruction(s) due to conditional branch succeeding\n",
719 size
, add_commas (buf1
, sizeof (buf1
), cond_jump
));
721 (*d10v_callback
->printf_filtered
) (d10v_callback
,
722 "executed %*s cycle(s)\n",
723 size
, add_commas (buf1
, sizeof (buf1
), cycles
));
725 (*d10v_callback
->printf_filtered
) (d10v_callback
,
726 "executed %*s total instructions\n",
727 size
, add_commas (buf1
, sizeof (buf1
), total
));
731 sim_create_inferior (start_address
, argv
, env
)
732 SIM_ADDR start_address
;
738 (*d10v_callback
->printf_filtered
) (d10v_callback
, "sim_create_inferior: PC=0x%x\n", start_address
);
741 /* reset all state information */
742 memset (&State
.regs
, 0, (int)&State
.imem
- (int)&State
.regs
[0]);
745 PC
= start_address
>> 2;
747 /* cpu resets imap0 to 0 and imap1 to 0x7f, but D10V-EVA board */
748 /* resets imap0 and imap1 to 0x1000. */
766 /* printf ("sim_set_callbacks\n"); */
771 sim_stop_reason (reason
, sigrc
)
772 enum sim_stop
*reason
;
775 /* (*d10v_callback->printf_filtered) (d10v_callback, "sim_stop_reason: PC=0x%x\n",PC<<2); */
777 switch (State
.exception
)
779 case SIG_D10V_STOP
: /* stop instruction */
780 *reason
= sim_exited
;
784 case SIG_D10V_EXIT
: /* exit trap */
785 *reason
= sim_exited
;
786 *sigrc
= State
.regs
[2];
789 default: /* some signal */
790 *reason
= sim_stopped
;
791 *sigrc
= State
.exception
;
797 sim_fetch_register (rn
, memory
)
799 unsigned char *memory
;
805 WRITE_64 (memory
, State
.a
[rn
-32]);
807 WRITE_16 (memory
, IMAP0
);
809 WRITE_16 (memory
, IMAP1
);
811 WRITE_16 (memory
, DMAP
);
813 WRITE_16 (memory
, State
.regs
[rn
]);
817 sim_store_register (rn
, memory
)
819 unsigned char *memory
;
825 State
.a
[rn
-32] = READ_64 (memory
) & MASK40
;
827 SET_DMAP( READ_16(memory
) );
829 SET_IMAP1( READ_16(memory
) );
831 SET_IMAP0( READ_16(memory
) );
833 State
.regs
[rn
]= READ_16 (memory
);
841 (*d10v_callback
->printf_filtered
) (d10v_callback
, "sim_do_command: %s\n",cmd
);
845 sim_load (prog
, from_tty
)
849 /* Return nonzero so GDB will handle it. */
This page took 0.046826 seconds and 4 git commands to generate.