Revisão | 4ce44c668ddc0a909c3f081d98c68bea90a93af9 (tree) |
---|---|
Hora | 1999-11-17 11:31:06 |
Autor | Jason Molenda <jmolenda@appl...> |
Commiter | Jason Molenda |
import gdb-1999-11-16 snapshot
@@ -1,3 +1,199 @@ | ||
1 | +1999-11-16 Mark Salter <msalter@cygnus.com> | |
2 | + | |
3 | + * monitor.c (monitor_supply_register): Initialize value to zero. | |
4 | + | |
5 | +1999-11-15 Eli Zaretskii <eliz@is.elta.co.il> | |
6 | + | |
7 | + (Patches applied by Jim Blandy <jimb@zwingli.cygnus.com>) | |
8 | + | |
9 | + Change DJGPP target use the common register layout in | |
10 | + config/i386/tm-i386.h. | |
11 | + * config/i386/tm-go32.h: #include "i386/tm-i386.h", not | |
12 | + "i386/tm-i386v.h". | |
13 | + (HAVE_I387_REGS): Define. | |
14 | + (HAVE_SSE_REGS): Undefine. | |
15 | + (NUM_FREGS, NUM_REGS, REGISTER_NAMES, FP_REGNUM, SP_REGNUM, | |
16 | + PS_REGNUM, PC_REGNUM, FP0_REGNUM, FPC_REGNUM, FPCWD_REGNUM, | |
17 | + FPSWD_REGNUM, FPTWD_REGNUM, FPIPO_REGNUM, FPIPS_REGNUM, | |
18 | + FPOOS_REGNUM, FPOPS_REGNUM, REGISTER_BYTES, REGISTER_BYTE, | |
19 | + REGBYTE_0, REGBYTE_10 REGBYTE_16, REGBYTE_24, REGBYTE_29, | |
20 | + REGISTER_RAW_SIZE, REGISTER_VIRTUAL_SIZE, MAX_REGISTER_RAW_SIZE, | |
21 | + MAX_REGISTER_VIRTUAL_SIZE, REGISTER_CONVERTIBLE): Definitions | |
22 | + deleted. | |
23 | + (i387_to_double, double_to_i387): Declarations deleted. | |
24 | + (REGISTER_CONVERT_TO_VIRTUAL, REGISTER_CONVERT_TO_RAW, | |
25 | + REGISTER_VIRTUAL_TYPE): Use definitions from | |
26 | + config/i386/tm-i386.h, unless LD_I387 is #defined. | |
27 | + | |
28 | + * go32-nat.c (go32_fetch_registers, store_register) | |
29 | + (go32_create_inferior, init_go32_ops): Replace fatal with | |
30 | + internal_error. | |
31 | + (sig_map): Map exception 7 to TARGET_SIGNAL_EMT. | |
32 | + | |
33 | + * utils.c (notice_quit): Doc fixes. | |
34 | + | |
35 | +1999-11-15 Kevin Buettner <kevinb@cygnus.com> | |
36 | + | |
37 | + * gdbserver/server.h (initialize_low): Declare this target | |
38 | + specific function. | |
39 | + * gdbserver/server.c (main): Call initialize_low. | |
40 | + * gdbserver/low-hppabsd.c, gdbserver/low-linux.c, | |
41 | + gdbserver/low-sim.c, gdbserver/low-sparc.c, gdbserver/low-sun3.c | |
42 | + (initialize_low): Renamed from initialize. Also removed | |
43 | + initialization of inferior_pid. | |
44 | + (have_inferior_p): Removed. | |
45 | + * gdbserver/low-lynx.c (initialize_low): New function. | |
46 | + | |
47 | +1999-11-12 Fernando Nasser <fnasser@totem.to.cygnus.com> | |
48 | + | |
49 | + * remote-rdi.c: Fix indentation accordingly to GNU standards. | |
50 | + | |
51 | +Thu Oct 28 00:28:51 1999 Andrew Cagney <cagney@b1.cygnus.com> | |
52 | + | |
53 | + * d10v-tdep.c (d10v_gdbarch_init): Make the d10v:ts3 the default. | |
54 | + | |
55 | +Tue Oct 26 09:57:29 1999 Andrew Cagney <cagney@b1.cygnus.com> | |
56 | + | |
57 | + * gdbarch.sh: Re-sync with Cagney's earlier const change. | |
58 | + | |
59 | +Sun Oct 24 20:07:31 1999 Andrew Cagney <cagney@b1.cygnus.com> | |
60 | + | |
61 | + * d10v-tdep.c (struct gdbarch_tdep): Replace nr_a_regs, | |
62 | + imap0_regnum, nr_imap_regs, dmap0_regnum, with dmap_register and | |
63 | + imap_register. | |
64 | + (R0_REGNUM, LR_REGNUM, PSW_REGNUM, NR_IMAP_REGS, NR_A_REGS): | |
65 | + Convert to enums. | |
66 | + (TS2_NR_A_REGS, TS2_NR_IMAP_REGS, TS3_NR_IMAP_REGS, | |
67 | + TS3_NR_A_REGS): Delete. | |
68 | + (d10v_ts2_dmap_register, d10v_ts3_dmap_register, | |
69 | + d10v_ts2_imap_register, d10v_ts3_imap_register): New functions. | |
70 | + (d10v_dmap_register, d10v_imap_register, | |
71 | + d10v_ts2_register_sim_regno, d10v_ts3_register_sim_regno, | |
72 | + show_regs): Update. | |
73 | + (remote_d10v_translate_xfer_address): Rewrite. Use | |
74 | + sim_d10v_translate_addr to translate addresses. | |
75 | + (d10v_gdbarch_init): Initialize tdep members dmap_register and | |
76 | + imap_register. | |
77 | + | |
78 | +Sun Oct 24 00:12:44 1999 Andrew Cagney <cagney@b1.cygnus.com> | |
79 | + | |
80 | + * d10v-tdep.c (struct gdbarch_tdep): Declare. | |
81 | + (NR_IMAP_REGS, NR_DMAP_REGS, A0_REGNUM, NR_A_REGS): Redefine using | |
82 | + value in gdbarch_tdep. | |
83 | + (d10v_dmap_register, d10v_imap_register): Ditto. | |
84 | + (d10v_ts2_register_name, d10v_ts2_register_sim_regno): Rename | |
85 | + d10v_register_name and d10v_register_sim_regno | |
86 | + (enum ts3_regnums, d10v_ts3_register_name, | |
87 | + d10v_ts3_register_sim_regno, d10v_register_sim_regno): New. | |
88 | + (d10v_gdbarch_init): Configure registers and G packet according to | |
89 | + d10v/ts2 and d10v/ts3. | |
90 | + | |
91 | +Sat Oct 23 21:28:02 1999 Andrew Cagney <cagney@b1.cygnus.com> | |
92 | + | |
93 | + * config/d10v/tm-d10v.h (IMAP0_REGNUM, IMAP1_REGNUM, DMAP_REGNUM): | |
94 | + Delete macro. | |
95 | + (R0_REGNUM, LR_REGNUM, PSW_REGNUM, A0_REGNUM): Move from here. | |
96 | + * d10v-tdep.c: To here. | |
97 | + | |
98 | + * d10v-tdep.c: (NR_DMAP_REGS, NR_IMAP_REGS, NR_A_REGS): Define. | |
99 | + (d10v_dmap_register, d10v_imap_register): New functions. | |
100 | + (remote_d10v_translate_xfer_address): Make static. | |
101 | + (d10v_register_virtual_size): Use TYPE_LENGTH of | |
102 | + REGISTER_VIRTUAL_TYPE. | |
103 | + (d10v_register_byte, do_d10v_pop_frame, | |
104 | + remote_d10v_translate_xfer_address, show_regs, | |
105 | + d10v_register_raw_size): Ditto. | |
106 | + (d10v_register_virtual_type): Ditto. Use explicitly sized builtin | |
107 | + types. | |
108 | + | |
109 | +Sat Oct 23 19:08:39 1999 Andrew Cagney <cagney@b1.cygnus.com> | |
110 | + | |
111 | + * d10v-tdep.c: Include "sim-d10v.h". | |
112 | + (enum ts2_regnums): Declare. | |
113 | + (d10v_register_sim_regno): New function. | |
114 | + | |
115 | + * config/d10v/tm-d10v.h: Delete pre multi-arch code. | |
116 | + (REGISTER_SIM_REGNO): Define. | |
117 | + (d10v_register_sim_regno): Declare. | |
118 | + | |
119 | +Sat Oct 23 16:39:34 1999 Andrew Cagney <cagney@b1.cygnus.com> | |
120 | + | |
121 | + * gdbarch.c (initialize_current_architecture): Make ``choice'' | |
122 | + const. | |
123 | + | |
124 | +Wed Nov 10 16:10:22 1999 Jeffrey A Law (law@cygnus.com) | |
125 | + | |
126 | + * hppa-tdep.c (hppa_fix_call_dummy): Fix typo in error message. | |
127 | + | |
128 | +Wed Nov 10 16:47:06 1999 Andrew Cagney <cagney@b1.cygnus.com> | |
129 | + | |
130 | + * utils.c (error_last_message): Use gdb_file_xstrdup. | |
131 | + | |
132 | + * defs.h (verror, internal_verror): Declare. | |
133 | + | |
134 | + * utils.c (verror, internal_error): New functions. | |
135 | + (error, internal_error): Use verror / internal_verror. | |
136 | + (error_stream): Use gdb_file_xstrdup. Correctly handle %s in | |
137 | + error message body. | |
138 | + (error_init): Use mem_fileopen. | |
139 | + | |
140 | + * corefile.c (memory_error): Use mem_fileopen instead of | |
141 | + tui_sfileopen. Don't call error_begin. | |
142 | + * remote-sim.c (gdb_os_error): Rewrite using verror. Don't call | |
143 | + error_begin. | |
144 | + | |
145 | +Wed Nov 10 14:21:43 1999 Andrew Cagney <cagney@b1.cygnus.com> | |
146 | + | |
147 | + * defs.h (gdb_file_xstrdup): New function. | |
148 | + * utils.c (gdb_file_xstrdup, do_gdb_file_xstrdup): Implement. | |
149 | + | |
150 | +1999-11-09 Stan Shebs <shebs@andros.cygnus.com> | |
151 | + | |
152 | + * exec.c (exec_file_attach), irix5-nat.c, osfsolib.c, solib.c | |
153 | + (info_sharedlibrary_command), pa64solib.c | |
154 | + (pa64_sharedlibrary_info_command), somsolib.c | |
155 | + (som_sharedlibrary_info_command): Replace "exec file" with | |
156 | + "executable file" in messages. | |
157 | + | |
158 | +1999-11-09 Jim Blandy <jimb@zwingli.cygnus.com> | |
159 | + | |
160 | + Finish the job attempted by the previous change. | |
161 | + * stabsread.c (read_range_type): Make n2 and n3 LONGEST. Adjust | |
162 | + the various tests that check for maximum values, bit counts, etc. | |
163 | + In the long run, it might have been simpler just to give GDB bignums. | |
164 | + | |
165 | +Tue Nov 9 18:34:13 1999 Andrew Cagney <cagney@amy.cygnus.com> | |
166 | + | |
167 | + * defs.h (gdb_file_put): Add parameter write. | |
168 | + (gdb_file_put_method_ftype): New typedef. | |
169 | + * utils.c (gdb_file_put, mem_file_put, tui_file_put, | |
170 | + null_file_put): Update. | |
171 | + | |
172 | + * utils.c (struct gdb_file): Add field magic. | |
173 | + (gdb_file_new): Initialize. | |
174 | + (gdb_file_data): Verify. | |
175 | + | |
176 | + * utils.c (mem_file_fputs): Delete. Replaced by. | |
177 | + (mem_file_write): New function. Rewrite mem_file. | |
178 | + (mem_file_new): Update. | |
179 | + | |
180 | +Tue Nov 9 17:51:12 1999 Andrew Cagney <cagney@b1.cygnus.com> | |
181 | + | |
182 | + * remote-sim.c (gdb_os_write_stdout): Use gdb_file_write. | |
183 | + (gdb_os_flush_stdout): Flush gdb_stdtarg instead of gdb_stdout. | |
184 | + | |
185 | +Tue Nov 9 15:33:43 1999 Andrew Cagney <cagney@b1.cygnus.com> | |
186 | + | |
187 | + * Makefile.in (procfs.o): Don't compile with -Werror for moment. | |
188 | + * sol-thread.c (info_cb): Move assignments to outside of if | |
189 | + statement. | |
190 | + (info_cb): Use paddr when printing addresses. | |
191 | + | |
192 | +1999-11-08 Jim Blandy <jimb@zenia.red-bean.com> | |
193 | + | |
194 | + * defs.h (ULONGEST_MAX, LONGEST_MAX): New definitions. | |
195 | + * stabsread.c (read_huge_number): Parse and return LONGEST values. | |
196 | + | |
1 | 197 | 1999-11-08 Mark Salter <msalter@cygnus.com> |
2 | 198 | |
3 | 199 | * utils.c (floatformat_to_doublest): Fix conversion of denormals. |
@@ -423,7 +619,10 @@ Thu Nov 4 17:36:27 1999 Andrew Cagney <cagney@b1.cygnus.com> | ||
423 | 619 | * gdbtypes.c (init_simd_type): The upper bound to |
424 | 620 | create_range_type is inclusive, not exclusive. |
425 | 621 | |
426 | - * configure.in: Check for PTRACE_GETXFPREGS, and #define | |
622 | + Add preliminary support for the Pentium-III's Streaming SIMD | |
623 | + Extensions --- specifically, the ability to read the XMM | |
624 | + registers. | |
625 | + * Configure.in: Check for PTRACE_GETXFPREGS, and #define | |
427 | 626 | HAVE_PTRACE_GETXFPREGS if we have it. |
428 | 627 | * acconfig.h: Add entry for HAVE_PTRACE_GETXFPREGS. |
429 | 628 | * configure, config.in: Regenerated. |
@@ -229,7 +229,7 @@ CDEPS = $(XM_CDEPS) $(TM_CDEPS) $(NAT_CDEPS) $(SIM) $(BFD) $(READLINE) \ | ||
229 | 229 | ADD_FILES = $(REGEX) $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES) |
230 | 230 | ADD_DEPS = $(REGEX1) $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES) |
231 | 231 | |
232 | -VERSION = 19991108 | |
232 | +VERSION = 19991116 | |
233 | 233 | DIST=gdb |
234 | 234 | |
235 | 235 | LINT=/usr/5bin/lint |
@@ -1407,8 +1407,11 @@ printcmd.o: printcmd.c $(breakpoint_h) $(defs_h) $(expression_h) \ | ||
1407 | 1407 | $(gdbcmd_h) $(gdbcore_h) $(gdbtypes_h) language.h objfiles.h \ |
1408 | 1408 | symfile.h $(symtab_h) target.h gdb_string.h |
1409 | 1409 | |
1410 | +# FIXME: Procfs.o gets -Wformat errors because things like pid_t don't | |
1411 | +# match output format strings. | |
1410 | 1412 | procfs.o: procfs.c $(command_h) $(defs_h) $(gdbcore_h) $(inferior_h) \ |
1411 | 1413 | target.h gdb_string.h |
1414 | + $(CC) -c $(INTERNAL_WARN_CFLAGS) $(NO_WERROR_CFLAGS) $< | |
1412 | 1415 | |
1413 | 1416 | sol-thread.o: sol-thread.c $(defs_h) gdbthread.h target.h $(inferior_h) \ |
1414 | 1417 | $(gdbcmd_h) |
@@ -2066,6 +2066,7 @@ print_it_typical (bs) | ||
2066 | 2066 | printf_filtered ("\n"); |
2067 | 2067 | return PRINT_UNKNOWN; |
2068 | 2068 | break; |
2069 | + | |
2069 | 2070 | /* Fall through, we don't deal with these types of breakpoints |
2070 | 2071 | here. */ |
2071 | 2072 |
@@ -2271,9 +2272,14 @@ watchpoint_check (p) | ||
2271 | 2272 | So we can't even detect the first assignment to it and |
2272 | 2273 | watch after that (since the garbage may or may not equal |
2273 | 2274 | the first value assigned). */ |
2275 | + /* We print all the stop information in print_it_typical(), but | |
2276 | + in this case, by the time we call print_it_typical() this bp | |
2277 | + will be deleted already. So we have no choice but print the | |
2278 | + information here. */ | |
2274 | 2279 | printf_filtered ("\ |
2275 | 2280 | Watchpoint %d deleted because the program has left the block in\n\ |
2276 | 2281 | which its expression is valid.\n", bs->breakpoint_at->number); |
2282 | + | |
2277 | 2283 | if (b->related_breakpoint) |
2278 | 2284 | b->related_breakpoint->disposition = del_at_next_stop; |
2279 | 2285 | b->disposition = del_at_next_stop; |
@@ -2408,6 +2414,9 @@ bpstat_stop_status (pc, not_a_breakpoint) | ||
2408 | 2414 | { |
2409 | 2415 | case WP_DELETED: |
2410 | 2416 | /* We've already printed what needs to be printed. */ |
2417 | + /* Actually this is superfluous, because by the time we | |
2418 | + call print_it_typical() the wp will be already deleted, | |
2419 | + and the function will return immediately. */ | |
2411 | 2420 | bs->print_it = print_it_done; |
2412 | 2421 | /* Stop. */ |
2413 | 2422 | break; |
@@ -22,290 +22,5 @@ | ||
22 | 22 | |
23 | 23 | #define GDB_MULTI_ARCH 1 |
24 | 24 | |
25 | -/* #define GDB_TARGET_IS_D10V - moved to gdbarch.h */ | |
26 | - | |
27 | -/* Define the bit, byte, and word ordering of the machine. */ | |
28 | - | |
29 | -#if !GDB_MULTI_ARCH | |
30 | - | |
31 | -#define TARGET_BYTE_ORDER BIG_ENDIAN | |
32 | - | |
33 | -/* Offset from address of function to start of its code. | |
34 | - Zero on most machines. */ | |
35 | - | |
36 | -#define FUNCTION_START_OFFSET 0 | |
37 | - | |
38 | -/* Advance PC across any function entry prologue instructions | |
39 | - to reach some "real" code. */ | |
40 | - | |
41 | -extern CORE_ADDR d10v_skip_prologue (); | |
42 | -#define SKIP_PROLOGUE(ip) (d10v_skip_prologue (ip)) | |
43 | - | |
44 | -/* Stack grows downward. */ | |
45 | -#define INNER_THAN(lhs,rhs) (core_addr_lessthan ((lhs), (rhs))) | |
46 | - | |
47 | -/* for a breakpoint, use "dbt || nop" */ | |
48 | -extern breakpoint_from_pc_fn d10v_breakpoint_from_pc; | |
49 | -#define BREAKPOINT_FROM_PC(PCPTR,LENPTR) (d10v_breakpoint_from_pc ((PCPTR), (LENPTR))) | |
50 | - | |
51 | -/* If your kernel resets the pc after the trap happens you may need to | |
52 | - define this before including this file. */ | |
53 | -#define DECR_PC_AFTER_BREAK 4 | |
54 | - | |
55 | -extern char *d10v_register_name PARAMS ((int reg_nr)); | |
56 | -#define REGISTER_NAME(NR) (d10v_register_name (NR)) | |
57 | - | |
58 | -#define NUM_REGS 37 | |
59 | - | |
60 | -#endif /* GDB_MULTI_ARCH */ | |
61 | - | |
62 | -/* Register numbers of various important registers. | |
63 | - Note that some of these values are "real" register numbers, | |
64 | - and correspond to the general registers of the machine, | |
65 | - and some are "phony" register numbers which are too large | |
66 | - to be actual register numbers as far as the user is concerned | |
67 | - but do serve to get the desired values when passed to read_register. */ | |
68 | - | |
69 | -/* Used by both d10v-tdep.c and remote-d10v.c */ | |
70 | - | |
71 | -#define R0_REGNUM 0 | |
72 | -#define LR_REGNUM 13 | |
73 | -#if !GDB_MULTI_ARCH | |
74 | -#define SP_REGNUM 15 | |
75 | -#define FP_REGNUM 11 | |
76 | -#define PC_REGNUM 18 | |
77 | -#endif | |
78 | -#define PSW_REGNUM 16 | |
79 | -#define IMAP0_REGNUM 32 | |
80 | -#define IMAP1_REGNUM 33 | |
81 | -#define DMAP_REGNUM 34 | |
82 | -#define A0_REGNUM 35 | |
83 | - | |
84 | -#if !GDB_MULTI_ARCH | |
85 | - | |
86 | -/* ??? */ | |
87 | -#define REGISTER_SIZE 2 | |
88 | - | |
89 | -/* Say how much memory is needed to store a copy of the register set */ | |
90 | -#define REGISTER_BYTES ((37/*NUM_REGS*/-2)*2+16) | |
91 | - | |
92 | -/* Index within `registers' of the first byte of the space for | |
93 | - register N. */ | |
94 | -extern int d10v_register_byte PARAMS ((int reg_nr)); | |
95 | -#define REGISTER_BYTE(N) (d10v_register_byte (N)) | |
96 | - | |
97 | -/* Number of bytes of storage in the actual machine representation | |
98 | - for register N. */ | |
99 | -extern int d10v_register_raw_size PARAMS ((int reg_nr)); | |
100 | -#define REGISTER_RAW_SIZE(N) (d10v_register_raw_size (N)) | |
101 | - | |
102 | -/* Number of bytes of storage in the program's representation | |
103 | - for register N. */ | |
104 | -extern int d10v_register_virtual_size PARAMS ((int reg_nr)); | |
105 | -#define REGISTER_VIRTUAL_SIZE(N) (d10v_register_virtual_size (N)) | |
106 | - | |
107 | -/* Largest value REGISTER_RAW_SIZE can have. */ | |
108 | - | |
109 | -#define MAX_REGISTER_RAW_SIZE 8 | |
110 | - | |
111 | -/* Largest value REGISTER_VIRTUAL_SIZE can have. */ | |
112 | - | |
113 | -#define MAX_REGISTER_VIRTUAL_SIZE 8 | |
114 | - | |
115 | -/* Return the GDB type object for the "standard" data type | |
116 | - of data in register N. */ | |
117 | - | |
118 | -extern struct type *d10v_register_virtual_type PARAMS ((int reg_nr)); | |
119 | -#define REGISTER_VIRTUAL_TYPE(N) (d10v_register_virtual_type (N)) | |
120 | - | |
121 | -/* convert $pc and $sp to/from virtual addresses */ | |
122 | -extern int d10v_register_convertible PARAMS ((int nr)); | |
123 | -extern void d10v_register_convert_to_virtual PARAMS ((int regnum, struct type * type, char *from, char *to)); | |
124 | -extern void d10v_register_convert_to_raw PARAMS ((struct type * type, int regnum, char *from, char *to)); | |
125 | -#define REGISTER_CONVERTIBLE(N) (d10v_register_convertible ((N))) | |
126 | -#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \ | |
127 | - d10v_register_convert_to_virtual ((REGNUM), (TYPE), (FROM), (TO)) | |
128 | -#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \ | |
129 | - d10v_register_convert_to_raw ((TYPE), (REGNUM), (FROM), (TO)) | |
130 | - | |
131 | -extern CORE_ADDR d10v_make_daddr PARAMS ((CORE_ADDR x)); | |
132 | -#define D10V_MAKE_DADDR(x) (d10v_make_daddr (x)) | |
133 | -extern CORE_ADDR d10v_make_iaddr PARAMS ((CORE_ADDR x)); | |
134 | -#define D10V_MAKE_IADDR(x) (d10v_make_iaddr (x)) | |
135 | - | |
136 | -extern int d10v_daddr_p PARAMS ((CORE_ADDR x)); | |
137 | -#define D10V_DADDR_P(X) (d10v_daddr_p (X)) | |
138 | -extern int d10v_iaddr_p PARAMS ((CORE_ADDR x)); | |
139 | -#define D10V_IADDR_P(X) (d10v_iaddr_p (X)) | |
140 | - | |
141 | -extern CORE_ADDR d10v_convert_daddr_to_raw PARAMS ((CORE_ADDR x)); | |
142 | -#define D10V_CONVERT_DADDR_TO_RAW(X) (d10v_convert_daddr_to_raw (X)) | |
143 | -extern CORE_ADDR d10v_convert_iaddr_to_raw PARAMS ((CORE_ADDR x)); | |
144 | -#define D10V_CONVERT_IADDR_TO_RAW(X) (d10v_convert_iaddr_to_raw (X)) | |
145 | - | |
146 | -/* Store the address of the place in which to copy the structure the | |
147 | - subroutine will return. This is called from call_function. | |
148 | - | |
149 | - We store structs through a pointer passed in the first Argument | |
150 | - register. */ | |
151 | - | |
152 | -extern void d10v_store_struct_return PARAMS ((CORE_ADDR addr, CORE_ADDR sp)); | |
153 | -#define STORE_STRUCT_RETURN(ADDR, SP) d10v_store_struct_return ((ADDR), (SP)) | |
154 | - | |
155 | - | |
156 | -/* Write into appropriate registers a function return value | |
157 | - of type TYPE, given in virtual format. | |
158 | - | |
159 | - Things always get returned in RET1_REGNUM, RET2_REGNUM, ... */ | |
160 | - | |
161 | -extern void d10v_store_return_value PARAMS ((struct type * type, char *valbuf)); | |
162 | -#define STORE_RETURN_VALUE(TYPE,VALBUF) d10v_store_return_value ((TYPE), (VALBUF)) | |
163 | - | |
164 | - | |
165 | -/* Extract from an array REGBUF containing the (raw) register state | |
166 | - the address in which a function should return its structure value, | |
167 | - as a CORE_ADDR (or an expression that can be used as one). */ | |
168 | - | |
169 | -extern CORE_ADDR d10v_extract_struct_value_address PARAMS ((char *regbuf)); | |
170 | -#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (d10v_extract_struct_value_address ((REGBUF))) | |
171 | - | |
172 | -/* Should we use EXTRACT_STRUCT_VALUE_ADDRESS instead of | |
173 | - EXTRACT_RETURN_VALUE? GCC_P is true if compiled with gcc | |
174 | - and TYPE is the type (which is known to be struct, union or array). | |
175 | - | |
176 | - The d10v returns anything less than 8 bytes in size in | |
177 | - registers. */ | |
178 | - | |
179 | -extern use_struct_convention_fn d10v_use_struct_convention; | |
180 | -#define USE_STRUCT_CONVENTION(gcc_p, type) d10v_use_struct_convention (gcc_p, type) | |
181 | - | |
182 | - | |
183 | -/* Define other aspects of the stack frame. | |
184 | - we keep a copy of the worked out return pc lying around, since it | |
185 | - is a useful bit of info */ | |
186 | - | |
187 | -extern void d10v_init_extra_frame_info PARAMS ((int fromleaf, struct frame_info * fi)); | |
188 | -#define INIT_EXTRA_FRAME_INFO(fromleaf, fi) \ | |
189 | - d10v_init_extra_frame_info(fromleaf, fi) | |
190 | - | |
191 | -/* A macro that tells us whether the function invocation represented | |
192 | - by FI does not have a frame on the stack associated with it. If it | |
193 | - does not, FRAMELESS is set to 1, else 0. */ | |
194 | - | |
195 | -#define FRAMELESS_FUNCTION_INVOCATION(FI) \ | |
196 | - (frameless_look_for_prologue (FI)) | |
197 | - | |
198 | -extern CORE_ADDR d10v_frame_chain PARAMS ((struct frame_info * frame)); | |
199 | -#define FRAME_CHAIN(FRAME) d10v_frame_chain(FRAME) | |
200 | -extern int d10v_frame_chain_valid PARAMS ((CORE_ADDR, struct frame_info *)); | |
201 | -#define FRAME_CHAIN_VALID(chain, thisframe) d10v_frame_chain_valid (chain, thisframe) | |
202 | -extern CORE_ADDR d10v_frame_saved_pc PARAMS ((struct frame_info * fi)); | |
203 | -#define FRAME_SAVED_PC(fi) (d10v_frame_saved_pc ((fi))) | |
204 | -extern CORE_ADDR d10v_frame_args_address PARAMS ((struct frame_info * fi)); | |
205 | -#define FRAME_ARGS_ADDRESS(fi) (d10v_frame_args_address ((fi))) | |
206 | -extern CORE_ADDR d10v_frame_locals_address PARAMS ((struct frame_info * fi)); | |
207 | -#define FRAME_LOCALS_ADDRESS(fi) (d10v_frame_locals_address ((fi))) | |
208 | - | |
209 | -/* Immediately after a function call, return the saved pc. We can't */ | |
210 | -/* use frame->return_pc beause that is determined by reading R13 off the */ | |
211 | -/*stack and that may not be written yet. */ | |
212 | - | |
213 | -extern CORE_ADDR d10v_saved_pc_after_call PARAMS ((struct frame_info * frame)); | |
214 | -#define SAVED_PC_AFTER_CALL(frame) (d10v_saved_pc_after_call ((frame))) | |
215 | - | |
216 | -/* Set VAL to the number of args passed to frame described by FI. | |
217 | - Can set VAL to -1, meaning no way to tell. */ | |
218 | -/* We can't tell how many args there are */ | |
219 | - | |
220 | -#define FRAME_NUM_ARGS(fi) (-1) | |
221 | - | |
222 | -/* Return number of bytes at start of arglist that are not really args. */ | |
223 | - | |
224 | -#define FRAME_ARGS_SKIP 0 | |
225 | - | |
226 | -/* Put here the code to store, into frame_info->saved_regs, the | |
227 | - addresses of the saved registers of frame described by FRAME_INFO. | |
228 | - This includes special registers such as pc and fp saved in special | |
229 | - ways in the stack frame. sp is even more special: the address we | |
230 | - return for it IS the sp for the next frame. */ | |
231 | - | |
232 | -extern void d10v_frame_init_saved_regs PARAMS ((struct frame_info *)); | |
233 | -#define FRAME_INIT_SAVED_REGS(frame_info) \ | |
234 | - d10v_frame_init_saved_regs(frame_info) | |
235 | - | |
236 | -/* DUMMY FRAMES. Need these to support inferior function calls. They | |
237 | - work like this on D10V: First we set a breakpoint at 0 or __start. | |
238 | - Then we push all the registers onto the stack. Then put the | |
239 | - function arguments in the proper registers and set r13 to our | |
240 | - breakpoint address. Finally, the PC is set to the start of the | |
241 | - function being called (no JSR/BSR insn). When it hits the | |
242 | - breakpoint, clear the break point and pop the old register contents | |
243 | - off the stack. */ | |
244 | - | |
245 | -extern void d10v_pop_frame PARAMS ((void)); | |
246 | -#define POP_FRAME d10v_pop_frame () | |
247 | - | |
248 | -#define USE_GENERIC_DUMMY_FRAMES 1 | |
249 | -#define CALL_DUMMY {0} | |
250 | -#define CALL_DUMMY_START_OFFSET (0) | |
251 | -#define CALL_DUMMY_BREAKPOINT_OFFSET (0) | |
252 | -#define CALL_DUMMY_LOCATION AT_ENTRY_POINT | |
253 | -#define FIX_CALL_DUMMY(DUMMY, START, FUNADDR, NARGS, ARGS, TYPE, GCCP) | |
254 | -#define CALL_DUMMY_ADDRESS() entry_point_address () | |
255 | -extern CORE_ADDR d10v_push_return_address PARAMS ((CORE_ADDR pc, CORE_ADDR sp)); | |
256 | -#define PUSH_RETURN_ADDRESS(PC, SP) d10v_push_return_address (PC, SP) | |
257 | - | |
258 | -#define PC_IN_CALL_DUMMY(PC, SP, FP) generic_pc_in_call_dummy (PC, SP, FP) | |
259 | -/* #define PC_IN_CALL_DUMMY(pc, sp, frame_address) ( pc == IMEM_START + 4 ) */ | |
260 | - | |
261 | -#define PUSH_DUMMY_FRAME generic_push_dummy_frame () | |
262 | - | |
263 | -/* override the default get_saved_register function with one that | |
264 | - takes account of generic CALL_DUMMY frames */ | |
265 | -#define GET_SAVED_REGISTER(raw_buffer, optimized, addrp, frame, regnum, lval) \ | |
266 | - generic_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval) | |
267 | - | |
268 | -#define PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr) \ | |
269 | - (d10v_push_arguments((nargs), (args), (sp), (struct_return), (struct_addr))) | |
270 | -extern CORE_ADDR d10v_push_arguments PARAMS ((int, struct value **, CORE_ADDR, int, CORE_ADDR)); | |
271 | - | |
272 | - | |
273 | -/* Extract from an array REGBUF containing the (raw) register state | |
274 | - a function return value of type TYPE, and copy that, in virtual format, | |
275 | - into VALBUF. */ | |
276 | - | |
277 | -#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \ | |
278 | -d10v_extract_return_value(TYPE, REGBUF, VALBUF) | |
279 | -extern void d10v_extract_return_value PARAMS ((struct type *, char *, char *)); | |
280 | - | |
281 | - | |
282 | -void d10v_write_pc PARAMS ((CORE_ADDR val, int pid)); | |
283 | -CORE_ADDR d10v_read_pc PARAMS ((int pid)); | |
284 | -void d10v_write_sp PARAMS ((CORE_ADDR val)); | |
285 | -CORE_ADDR d10v_read_sp PARAMS ((void)); | |
286 | -void d10v_write_fp PARAMS ((CORE_ADDR val)); | |
287 | -CORE_ADDR d10v_read_fp PARAMS ((void)); | |
288 | - | |
289 | -#define TARGET_READ_PC(pid) d10v_read_pc (pid) | |
290 | -#define TARGET_WRITE_PC(val,pid) d10v_write_pc (val, pid) | |
291 | -#define TARGET_READ_FP() d10v_read_fp () | |
292 | -#define TARGET_WRITE_FP(val) d10v_write_fp (val) | |
293 | -#define TARGET_READ_SP() d10v_read_sp () | |
294 | -#define TARGET_WRITE_SP(val) d10v_write_sp (val) | |
295 | - | |
296 | -/* Number of bits in the appropriate type */ | |
297 | -#define TARGET_INT_BIT (2 * TARGET_CHAR_BIT) | |
298 | -#define TARGET_PTR_BIT (4 * TARGET_CHAR_BIT) | |
299 | -#define TARGET_DOUBLE_BIT (4 * TARGET_CHAR_BIT) | |
300 | -#define TARGET_LONG_DOUBLE_BIT (8 * TARGET_CHAR_BIT) | |
301 | - | |
302 | - | |
303 | -/* For the d10v when talking to the remote d10v board, GDB addresses | |
304 | - need to be translated into a format that the d10v rom monitor | |
305 | - understands. */ | |
306 | - | |
307 | -extern void remote_d10v_translate_xfer_address PARAMS ((CORE_ADDR gdb_addr, int gdb_len, CORE_ADDR * rem_addr, int *rem_len)); | |
308 | -#define REMOTE_TRANSLATE_XFER_ADDRESS(GDB_ADDR, GDB_LEN, REM_ADDR, REM_LEN) \ | |
309 | - remote_d10v_translate_xfer_address ((GDB_ADDR), (GDB_LEN), (REM_ADDR), (REM_LEN)) | |
310 | - | |
311 | -#endif | |
25 | +extern int d10v_register_sim_regno (int reg); | |
26 | +#define REGISTER_SIM_REGNO(NR) d10v_register_sim_regno((NR)) |
@@ -18,108 +18,10 @@ | ||
18 | 18 | Foundation, Inc., 59 Temple Place - Suite 330, |
19 | 19 | Boston, MA 02111-1307, USA. */ |
20 | 20 | |
21 | -#include "i386/tm-i386v.h" | |
22 | - | |
23 | -/* Number of machine registers. */ | |
24 | - | |
25 | -#undef NUM_FREGS | |
26 | -#define NUM_FREGS 15 | |
27 | -#undef NUM_REGS | |
28 | -#define NUM_REGS (16+NUM_FREGS) | |
29 | - | |
30 | -/* Initializer for an array of names of registers. There should be | |
31 | - NUM_REGS strings in this initializer. */ | |
32 | - | |
33 | -/* The order of the first 8 registers must match the compiler's | |
34 | - numbering scheme (which is the same as the 386 scheme). */ | |
35 | - | |
36 | -#undef REGISTER_NAMES | |
37 | -#define REGISTER_NAMES { "eax", "ecx", "edx", "ebx", \ | |
38 | - "esp", "ebp", "esi", "edi", \ | |
39 | - "eip", "eflags","cs", "ss", \ | |
40 | - "ds", "es", "fs", "gs", \ | |
41 | - "st0", "st1", "st2", "st3", \ | |
42 | - "st4", "st5", "st6", "st7", \ | |
43 | - "fctrl","fstat", "ftag", "fcs", \ | |
44 | - "fopsel","fip", "fopoff" } | |
45 | - | |
46 | -#undef FP_REGNUM | |
47 | -#define FP_REGNUM 5 /* (ebp) Contains addr of stack frame */ | |
48 | -#undef SP_REGNUM | |
49 | -#define SP_REGNUM 4 /* (usp) Contains address of top of stack */ | |
50 | -#undef PS_REGNUM | |
51 | -#define PS_REGNUM 9 /* (ps) Contains processor status */ | |
52 | -#undef PC_REGNUM | |
53 | -#define PC_REGNUM 8 /* (eip) Contains program counter */ | |
54 | -#undef FP0_REGNUM | |
55 | -#define FP0_REGNUM 16 /* Floating point register 0 */ | |
56 | -#undef FPC_REGNUM | |
57 | -#define FPC_REGNUM 24 /* 80387 control register */ | |
58 | -#undef FPCWD_REGNUM | |
59 | -#define FPCWD_REGNUM FPC_REGNUM | |
60 | -#undef FPSWD_REGNUM | |
61 | -#define FPSWD_REGNUM 25 /* 80387 status register */ | |
62 | -#undef FPTWD_REGNUM | |
63 | -#define FPTWD_REGNUM 26 /* 80387 tag register */ | |
64 | -#undef FPIPO_REGNUM | |
65 | -#define FPIPO_REGNUM 29 /* 80387 instruction pointer offset reg */ | |
66 | -#undef FPIPS_REGNUM | |
67 | -#define FPIPS_REGNUM 27 /* 80387 instruction pointer selector reg */ | |
68 | -#undef FPOOS_REGNUM | |
69 | -#define FPOOS_REGNUM 30 /* 80387 operand pointer offset reg */ | |
70 | -#undef FPOPS_REGNUM | |
71 | -#define FPOPS_REGNUM 28 /* 80387 operand pointer selector reg */ | |
72 | - | |
73 | -/* Total amount of space needed to store our copies of the machine's | |
74 | - register state, the array `registers'. */ | |
75 | - | |
76 | -#undef REGISTER_BYTES | |
77 | -#define REGISTER_BYTES (10*4 + 6*2 + 8*10 + 5*2 + 2*4) | |
78 | - | |
79 | -/* Index within `registers' of the first byte of the space for | |
80 | - register N. */ | |
81 | - | |
82 | -#undef REGISTER_BYTE | |
83 | -#define REGBYTE_0 0 | |
84 | -#define REGBYTE_10 (REGBYTE_0+10*4) | |
85 | -#define REGBYTE_16 (REGBYTE_10+6*2) | |
86 | -#define REGBYTE_24 (REGBYTE_16+8*10) | |
87 | -#define REGBYTE_29 (REGBYTE_24+5*2) | |
88 | -#define REGISTER_BYTE(N) (((N) < 10) ? (N) * 4 : \ | |
89 | - (N) < 16 ? REGBYTE_10 +((N) - 10) * 2 : \ | |
90 | - (N) < 24 ? REGBYTE_16 +((N) - 16) * 10 : \ | |
91 | - (N) < 29 ? REGBYTE_24 +((N) - 24) * 2 : \ | |
92 | - REGBYTE_29 + ((N) - 29) * 4) | |
93 | - | |
94 | -/* Number of bytes of storage in the actual machine representation | |
95 | - for register N. */ | |
96 | - | |
97 | -#undef REGISTER_RAW_SIZE | |
98 | -#define REGISTER_RAW_SIZE(N) ((N) < 10 ? 4 : (N) < 16 ? 2 : (N) < 24 ? 10 : \ | |
99 | - (N) < 29 ? 2 : 4) | |
100 | - | |
101 | -/* Number of bytes of storage in the program's representation | |
102 | - for register N. */ | |
103 | - | |
104 | -#undef REGISTER_VIRTUAL_SIZE | |
105 | -#define REGISTER_VIRTUAL_SIZE(N) REGISTER_RAW_SIZE(N) | |
106 | - | |
107 | -/* Largest value REGISTER_RAW_SIZE can have. */ | |
108 | - | |
109 | -#undef MAX_REGISTER_RAW_SIZE | |
110 | -#define MAX_REGISTER_RAW_SIZE 10 | |
111 | - | |
112 | -/* Largest value REGISTER_VIRTUAL_SIZE can have. */ | |
113 | - | |
114 | -#undef MAX_REGISTER_VIRTUAL_SIZE | |
115 | -#define MAX_REGISTER_VIRTUAL_SIZE 10 | |
116 | - | |
117 | -/* Nonzero if register N requires conversion | |
118 | - from raw format to virtual format. */ | |
119 | - | |
120 | -#undef REGISTER_CONVERTIBLE | |
121 | -#define REGISTER_CONVERTIBLE(N) ((N) < FP0_REGNUM ? 0 :\ | |
122 | - (N) < FPC_REGNUM ? 1 : 0) | |
21 | +#undef HAVE_SSE_REGS /* FIXME! go32-nat.c needs to support XMMi registers */ | |
22 | +#define HAVE_I387_REGS | |
23 | + | |
24 | +#include "i386/tm-i386.h" | |
123 | 25 | |
124 | 26 | /* The host and target are i386 machines and the compiler supports |
125 | 27 | long doubles. Long doubles on the host therefore have the same |
@@ -142,70 +44,34 @@ | ||
142 | 44 | |
143 | 45 | extern int i387_hex_long_double_input (char *p, long double *putithere); |
144 | 46 | |
47 | +#ifdef LD_I387 /* otherwise, definitions from tm-i386.h are good enough */ | |
48 | + | |
145 | 49 | #undef REGISTER_CONVERT_TO_VIRTUAL |
146 | -#ifdef LD_I387 | |
147 | -#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \ | |
148 | -{ \ | |
149 | - if (TYPE == REGISTER_VIRTUAL_TYPE (REGNUM)) \ | |
150 | - { \ | |
151 | - memcpy (TO, FROM, TYPE_LENGTH (TYPE)); \ | |
152 | - } \ | |
153 | - else \ | |
154 | - { \ | |
155 | - long double val = *((long double *)FROM); \ | |
156 | - store_floating ((TO), TYPE_LENGTH (TYPE), val); \ | |
157 | - } \ | |
50 | +#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \ | |
51 | +{ \ | |
52 | + long double val = *((long double *)(FROM)); \ | |
53 | + store_floating ((TO), TYPE_LENGTH (TYPE), val); \ | |
158 | 54 | } |
159 | -#else | |
160 | -/* Convert data from raw format for register REGNUM in buffer FROM to | |
161 | - virtual format with type TYPE in buffer TO. */ | |
162 | -#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \ | |
163 | -{ \ | |
164 | - double val; \ | |
165 | - i387_to_double ((FROM), (char *)&val); \ | |
166 | - store_floating ((TO), TYPE_LENGTH (TYPE), val); \ | |
167 | -} | |
168 | -#endif | |
169 | - | |
170 | -extern void i387_to_double PARAMS ((char *, char *)); | |
171 | 55 | |
172 | 56 | #undef REGISTER_CONVERT_TO_RAW |
173 | -#ifdef LD_I387 | |
174 | -#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \ | |
175 | -{ \ | |
176 | - if (TYPE == REGISTER_VIRTUAL_TYPE (REGNUM)) \ | |
177 | - { \ | |
178 | - memcpy (TO, FROM, TYPE_LENGTH (TYPE)); \ | |
179 | - } \ | |
180 | - else \ | |
181 | - { \ | |
182 | - long double val = extract_floating ((FROM), TYPE_LENGTH (TYPE)); \ | |
183 | - *((long double *)TO) = val; \ | |
184 | - } \ | |
185 | -} | |
186 | -#else | |
187 | -#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \ | |
188 | -{ \ | |
189 | - double val = extract_floating ((FROM), TYPE_LENGTH (TYPE)); \ | |
190 | - double_to_i387((char *)&val, (TO)); \ | |
57 | +#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \ | |
58 | +{ \ | |
59 | + long double val = extract_floating ((FROM), TYPE_LENGTH (TYPE)); \ | |
60 | + *((long double *)(TO)) = val; \ | |
191 | 61 | } |
192 | -#endif | |
193 | 62 | |
194 | -extern void double_to_i387 PARAMS ((char *, char *)); | |
63 | +/* Return the GDB type object for the "standard" data type of data in | |
64 | + register N. Perhaps si and di should go here, but potentially they | |
65 | + could be used for things other than address. */ | |
195 | 66 | |
196 | -/* Return the GDB type object for the "standard" data type of data in | |
197 | - register N. */ | |
67 | +#define REGISTER_VIRTUAL_TYPE(N) \ | |
68 | + (((N) == PC_REGNUM || (N) == FP_REGNUM || (N) == SP_REGNUM) \ | |
69 | + ? lookup_pointer_type (builtin_type_void) \ | |
70 | + : IS_FP_REGNUM(N) ? builtin_type_long_double \ | |
71 | + : IS_SSE_REGNUM(N) ? builtin_type_v4sf \ | |
72 | + : builtin_type_int) | |
198 | 73 | |
199 | -#undef REGISTER_VIRTUAL_TYPE | |
200 | -#ifdef LD_I387 | |
201 | -#define REGISTER_VIRTUAL_TYPE(N) \ | |
202 | - ((N < FP0_REGNUM) ? builtin_type_int : \ | |
203 | - (N < FPC_REGNUM) ? builtin_type_long_double : builtin_type_int) | |
204 | -#else | |
205 | -#define REGISTER_VIRTUAL_TYPE(N) \ | |
206 | - ((N < FP0_REGNUM) ? builtin_type_int : \ | |
207 | - (N < FPC_REGNUM) ? builtin_type_double : builtin_type_int) | |
208 | -#endif | |
74 | +#endif /* LD_I387 */ | |
209 | 75 | |
210 | 76 | #undef TARGET_LONG_DOUBLE_BIT |
211 | 77 | #define TARGET_LONG_DOUBLE_BIT 96 |
@@ -148,11 +148,11 @@ extern int i386_skip_prologue PARAMS ((int)); | ||
148 | 148 | #define FP0_REGNUM 16 /* first FPU floating-point register */ |
149 | 149 | #define FP7_REGNUM 23 /* last FPU floating-point register */ |
150 | 150 | |
151 | -/* All of these control registers are sixteen bits long (at most) in | |
152 | - the FPU, but are zero-extended to thirty-two bits in GDB's register | |
153 | - file. This makes it easier to compute the size of the control | |
154 | - register file, and somewhat easier to convert to and from the FSAVE | |
155 | - instruction's 32-bit format. */ | |
151 | +/* All of these control registers (except for FCOFF and FDOFF) are | |
152 | + sixteen bits long (at most) in the FPU, but are zero-extended to | |
153 | + thirty-two bits in GDB's register file. This makes it easier to | |
154 | + compute the size of the control register file, and somewhat easier | |
155 | + to convert to and from the FSAVE instruction's 32-bit format. */ | |
156 | 156 | #define FIRST_FPU_CTRL_REGNUM 24 |
157 | 157 | #define FCTRL_REGNUM 24 /* FPU control word */ |
158 | 158 | #define FPC_REGNUM 24 /* old name for FCTRL_REGNUM */ |
@@ -236,11 +236,9 @@ memory_error (status, memaddr) | ||
236 | 236 | int status; |
237 | 237 | CORE_ADDR memaddr; |
238 | 238 | { |
239 | - GDB_FILE *tmp_stream = tui_sfileopen (130); | |
239 | + struct gdb_file *tmp_stream = mem_fileopen (); | |
240 | 240 | make_cleanup_gdb_file_delete (tmp_stream); |
241 | 241 | |
242 | - error_begin (); | |
243 | - | |
244 | 242 | if (status == EIO) |
245 | 243 | { |
246 | 244 | /* Actually, address between memaddr and memaddr + len |
@@ -35,6 +35,11 @@ | ||
35 | 35 | #include "objfiles.h" |
36 | 36 | #include "language.h" |
37 | 37 | |
38 | +#include "sim-d10v.h" | |
39 | + | |
40 | +#undef XMALLOC | |
41 | +#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE))) | |
42 | + | |
38 | 43 | struct frame_extra_info |
39 | 44 | { |
40 | 45 | CORE_ADDR return_pc; |
@@ -42,14 +47,36 @@ struct frame_extra_info | ||
42 | 47 | int size; |
43 | 48 | }; |
44 | 49 | |
45 | -/* these are the addresses the D10V-EVA board maps data */ | |
46 | -/* and instruction memory to. */ | |
50 | +struct gdbarch_tdep | |
51 | + { | |
52 | + int a0_regnum; | |
53 | + int nr_dmap_regs; | |
54 | + unsigned long (*dmap_register) (int nr); | |
55 | + unsigned long (*imap_register) (int nr); | |
56 | + int (*register_sim_regno) (int nr); | |
57 | + }; | |
58 | + | |
59 | +/* These are the addresses the D10V-EVA board maps data and | |
60 | + instruction memory to. */ | |
47 | 61 | |
48 | 62 | #define DMEM_START 0x2000000 |
49 | 63 | #define IMEM_START 0x1000000 |
50 | 64 | #define STACK_START 0x0007ffe |
51 | 65 | |
52 | -/* d10v register naming conventions */ | |
66 | +/* d10v register names. */ | |
67 | + | |
68 | +enum | |
69 | + { | |
70 | + R0_REGNUM = 0, | |
71 | + LR_REGNUM = 13, | |
72 | + PSW_REGNUM = 16, | |
73 | + NR_IMAP_REGS = 2, | |
74 | + NR_A_REGS = 2 | |
75 | + }; | |
76 | +#define NR_DMAP_REGS (gdbarch_tdep (current_gdbarch)->nr_dmap_regs) | |
77 | +#define A0_REGNUM (gdbarch_tdep (current_gdbarch)->a0_regnum) | |
78 | + | |
79 | +/* d10v calling convention. */ | |
53 | 80 | |
54 | 81 | #define ARG1_REGNUM R0_REGNUM |
55 | 82 | #define ARGN_REGNUM 3 |
@@ -69,9 +96,6 @@ extern void d10v_frame_init_saved_regs PARAMS ((struct frame_info *)); | ||
69 | 96 | |
70 | 97 | static void do_d10v_pop_frame PARAMS ((struct frame_info * fi)); |
71 | 98 | |
72 | -/* FIXME */ | |
73 | -extern void remote_d10v_translate_xfer_address PARAMS ((CORE_ADDR gdb_addr, int gdb_len, CORE_ADDR * rem_addr, int *rem_len)); | |
74 | - | |
75 | 99 | int |
76 | 100 | d10v_frame_chain_valid (chain, frame) |
77 | 101 | CORE_ADDR chain; |
@@ -108,9 +132,19 @@ d10v_breakpoint_from_pc (pcptr, lenptr) | ||
108 | 132 | return breakpoint; |
109 | 133 | } |
110 | 134 | |
111 | -char * | |
112 | -d10v_register_name (reg_nr) | |
113 | - int reg_nr; | |
135 | +/* Map the REG_NR onto an ascii name. Return NULL or an empty string | |
136 | + when the reg_nr isn't valid. */ | |
137 | + | |
138 | +enum ts2_regnums | |
139 | + { | |
140 | + TS2_IMAP0_REGNUM = 32, | |
141 | + TS2_DMAP_REGNUM = 34, | |
142 | + TS2_NR_DMAP_REGS = 1, | |
143 | + TS2_A0_REGNUM = 35 | |
144 | + }; | |
145 | + | |
146 | +static char * | |
147 | +d10v_ts2_register_name (int reg_nr) | |
114 | 148 | { |
115 | 149 | static char *register_names[] = |
116 | 150 | { |
@@ -127,6 +161,120 @@ d10v_register_name (reg_nr) | ||
127 | 161 | return register_names[reg_nr]; |
128 | 162 | } |
129 | 163 | |
164 | +enum ts3_regnums | |
165 | + { | |
166 | + TS3_IMAP0_REGNUM = 36, | |
167 | + TS3_DMAP0_REGNUM = 38, | |
168 | + TS3_NR_DMAP_REGS = 4, | |
169 | + TS3_A0_REGNUM = 32 | |
170 | + }; | |
171 | + | |
172 | +static char * | |
173 | +d10v_ts3_register_name (int reg_nr) | |
174 | +{ | |
175 | + static char *register_names[] = | |
176 | + { | |
177 | + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", | |
178 | + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", | |
179 | + "psw", "bpsw", "pc", "bpc", "cr4", "cr5", "cr6", "rpt_c", | |
180 | + "rpt_s", "rpt_e", "mod_s", "mod_e", "cr12", "cr13", "iba", "cr15", | |
181 | + "a0", "a1", | |
182 | + "spi", "spu", | |
183 | + "imap0", "imap1", | |
184 | + "dmap0", "dmap1", "dmap2", "dmap3" | |
185 | + }; | |
186 | + if (reg_nr < 0) | |
187 | + return NULL; | |
188 | + if (reg_nr >= (sizeof (register_names) / sizeof (*register_names))) | |
189 | + return NULL; | |
190 | + return register_names[reg_nr]; | |
191 | +} | |
192 | + | |
193 | +/* Access the DMAP/IMAP registers in a target independant way. */ | |
194 | + | |
195 | +static unsigned long | |
196 | +d10v_ts2_dmap_register (int reg_nr) | |
197 | +{ | |
198 | + switch (reg_nr) | |
199 | + { | |
200 | + case 0: | |
201 | + case 1: | |
202 | + return 0x2000; | |
203 | + case 2: | |
204 | + return read_register (TS2_DMAP_REGNUM); | |
205 | + default: | |
206 | + return 0; | |
207 | + } | |
208 | +} | |
209 | + | |
210 | +static unsigned long | |
211 | +d10v_ts3_dmap_register (int reg_nr) | |
212 | +{ | |
213 | + return read_register (TS3_DMAP0_REGNUM + reg_nr); | |
214 | +} | |
215 | + | |
216 | +static unsigned long | |
217 | +d10v_dmap_register (int reg_nr) | |
218 | +{ | |
219 | + return gdbarch_tdep (current_gdbarch)->dmap_register (reg_nr); | |
220 | +} | |
221 | + | |
222 | +static unsigned long | |
223 | +d10v_ts2_imap_register (int reg_nr) | |
224 | +{ | |
225 | + return read_register (TS2_IMAP0_REGNUM + reg_nr); | |
226 | +} | |
227 | + | |
228 | +static unsigned long | |
229 | +d10v_ts3_imap_register (int reg_nr) | |
230 | +{ | |
231 | + return read_register (TS3_IMAP0_REGNUM + reg_nr); | |
232 | +} | |
233 | + | |
234 | +static unsigned long | |
235 | +d10v_imap_register (int reg_nr) | |
236 | +{ | |
237 | + return gdbarch_tdep (current_gdbarch)->imap_register (reg_nr); | |
238 | +} | |
239 | + | |
240 | +/* MAP GDB's internal register numbering (determined by the layout fo | |
241 | + the REGISTER_BYTE array) onto the simulator's register | |
242 | + numbering. */ | |
243 | + | |
244 | +static int | |
245 | +d10v_ts2_register_sim_regno (int nr) | |
246 | +{ | |
247 | + if (nr >= TS2_IMAP0_REGNUM | |
248 | + && nr < TS2_IMAP0_REGNUM + NR_IMAP_REGS) | |
249 | + return nr - TS2_IMAP0_REGNUM + SIM_D10V_IMAP0_REGNUM; | |
250 | + if (nr == TS2_DMAP_REGNUM) | |
251 | + return nr - TS2_DMAP_REGNUM + SIM_D10V_TS2_DMAP_REGNUM; | |
252 | + if (nr >= TS2_A0_REGNUM | |
253 | + && nr < TS2_A0_REGNUM + NR_A_REGS) | |
254 | + return nr - TS2_A0_REGNUM + SIM_D10V_A0_REGNUM; | |
255 | + return nr; | |
256 | +} | |
257 | + | |
258 | +static int | |
259 | +d10v_ts3_register_sim_regno (int nr) | |
260 | +{ | |
261 | + if (nr >= TS3_IMAP0_REGNUM | |
262 | + && nr < TS3_IMAP0_REGNUM + NR_IMAP_REGS) | |
263 | + return nr - TS3_IMAP0_REGNUM + SIM_D10V_IMAP0_REGNUM; | |
264 | + if (nr >= TS3_DMAP0_REGNUM | |
265 | + && nr < TS3_DMAP0_REGNUM + TS3_NR_DMAP_REGS) | |
266 | + return nr - TS3_DMAP0_REGNUM + SIM_D10V_DMAP0_REGNUM; | |
267 | + if (nr >= TS3_A0_REGNUM | |
268 | + && nr < TS3_A0_REGNUM + NR_A_REGS) | |
269 | + return nr - TS3_A0_REGNUM + SIM_D10V_A0_REGNUM; | |
270 | + return nr; | |
271 | +} | |
272 | + | |
273 | +int | |
274 | +d10v_register_sim_regno (int nr) | |
275 | +{ | |
276 | + return gdbarch_tdep (current_gdbarch)->register_sim_regno (nr); | |
277 | +} | |
130 | 278 | |
131 | 279 | /* Index within `registers' of the first byte of the space for |
132 | 280 | register REG_NR. */ |
@@ -135,10 +283,15 @@ int | ||
135 | 283 | d10v_register_byte (reg_nr) |
136 | 284 | int reg_nr; |
137 | 285 | { |
138 | - if (reg_nr > A0_REGNUM) | |
139 | - return ((reg_nr - A0_REGNUM) * 8 + (A0_REGNUM * 2)); | |
140 | - else | |
286 | + if (reg_nr < A0_REGNUM) | |
141 | 287 | return (reg_nr * 2); |
288 | + else if (reg_nr < (A0_REGNUM + NR_A_REGS)) | |
289 | + return (A0_REGNUM * 2 | |
290 | + + (reg_nr - A0_REGNUM) * 8); | |
291 | + else | |
292 | + return (A0_REGNUM * 2 | |
293 | + + NR_A_REGS * 8 | |
294 | + + (reg_nr - A0_REGNUM - NR_A_REGS) * 2); | |
142 | 295 | } |
143 | 296 | |
144 | 297 | /* Number of bytes of storage in the actual machine representation for |
@@ -148,7 +301,9 @@ int | ||
148 | 301 | d10v_register_raw_size (reg_nr) |
149 | 302 | int reg_nr; |
150 | 303 | { |
151 | - if (reg_nr >= A0_REGNUM) | |
304 | + if (reg_nr < A0_REGNUM) | |
305 | + return 2; | |
306 | + else if (reg_nr < (A0_REGNUM + NR_A_REGS)) | |
152 | 307 | return 8; |
153 | 308 | else |
154 | 309 | return 2; |
@@ -161,12 +316,7 @@ int | ||
161 | 316 | d10v_register_virtual_size (reg_nr) |
162 | 317 | int reg_nr; |
163 | 318 | { |
164 | - if (reg_nr >= A0_REGNUM) | |
165 | - return 8; | |
166 | - else if (reg_nr == PC_REGNUM || reg_nr == SP_REGNUM) | |
167 | - return 4; | |
168 | - else | |
169 | - return 2; | |
319 | + return TYPE_LENGTH (REGISTER_VIRTUAL_TYPE (reg_nr)); | |
170 | 320 | } |
171 | 321 | |
172 | 322 | /* Return the GDB type object for the "standard" data type |
@@ -176,12 +326,14 @@ struct type * | ||
176 | 326 | d10v_register_virtual_type (reg_nr) |
177 | 327 | int reg_nr; |
178 | 328 | { |
179 | - if (reg_nr >= A0_REGNUM) | |
180 | - return builtin_type_long_long; | |
181 | - else if (reg_nr == PC_REGNUM || reg_nr == SP_REGNUM) | |
182 | - return builtin_type_long; | |
329 | + if (reg_nr >= A0_REGNUM | |
330 | + && reg_nr < (A0_REGNUM + NR_A_REGS)) | |
331 | + return builtin_type_int64; | |
332 | + else if (reg_nr == PC_REGNUM | |
333 | + || reg_nr == SP_REGNUM) | |
334 | + return builtin_type_int32; | |
183 | 335 | else |
184 | - return builtin_type_short; | |
336 | + return builtin_type_int16; | |
185 | 337 | } |
186 | 338 | |
187 | 339 | /* convert $pc and $sp to/from virtual addresses */ |
@@ -363,7 +515,7 @@ do_d10v_pop_frame (fi) | ||
363 | 515 | d10v_frame_init_saved_regs (fi); |
364 | 516 | |
365 | 517 | /* now update the current registers with the old values */ |
366 | - for (regnum = A0_REGNUM; regnum < A0_REGNUM + 2; regnum++) | |
518 | + for (regnum = A0_REGNUM; regnum < A0_REGNUM + NR_A_REGS; regnum++) | |
367 | 519 | { |
368 | 520 | if (fi->saved_regs[regnum]) |
369 | 521 | { |
@@ -754,12 +906,24 @@ show_regs (args, from_tty) | ||
754 | 906 | (long) read_register (13), |
755 | 907 | (long) read_register (14), |
756 | 908 | (long) read_register (15)); |
757 | - printf_filtered ("IMAP0 %04lx IMAP1 %04lx DMAP %04lx\n", | |
758 | - (long) read_register (IMAP0_REGNUM), | |
759 | - (long) read_register (IMAP1_REGNUM), | |
760 | - (long) read_register (DMAP_REGNUM)); | |
761 | - printf_filtered ("A0-A1"); | |
762 | - for (a = A0_REGNUM; a <= A0_REGNUM + 1; a++) | |
909 | + for (a = 0; a < NR_IMAP_REGS; a++) | |
910 | + { | |
911 | + if (a > 0) | |
912 | + printf_filtered (" "); | |
913 | + printf_filtered ("IMAP%d %04lx", a, d10v_imap_register (a)); | |
914 | + } | |
915 | + if (NR_DMAP_REGS == 1) | |
916 | + printf_filtered (" DMAP %04lx\n", d10v_dmap_register (2)); | |
917 | + else | |
918 | + { | |
919 | + for (a = 0; a < NR_DMAP_REGS; a++) | |
920 | + { | |
921 | + printf_filtered (" DMAP%d %04lx", a, d10v_dmap_register (a)); | |
922 | + } | |
923 | + printf_filtered ("\n"); | |
924 | + } | |
925 | + printf_filtered ("A0-A%d", NR_A_REGS - 1); | |
926 | + for (a = A0_REGNUM; a < A0_REGNUM + NR_A_REGS; a++) | |
763 | 927 | { |
764 | 928 | char num[MAX_REGISTER_RAW_SIZE]; |
765 | 929 | int i; |
@@ -1032,163 +1196,25 @@ d10v_extract_return_value (type, regbuf, valbuf) | ||
1032 | 1196 | |
1033 | 1197 | /* Translate a GDB virtual ADDR/LEN into a format the remote target |
1034 | 1198 | understands. Returns number of bytes that can be transfered |
1035 | - starting at taddr, ZERO if no bytes can be transfered. */ | |
1199 | + starting at TARG_ADDR. Return ZERO if no bytes can be transfered | |
1200 | + (segmentation fault). Since the simulator knows all about how the | |
1201 | + VM system works, we just call that to do the translation. */ | |
1036 | 1202 | |
1037 | -void | |
1203 | +static void | |
1038 | 1204 | remote_d10v_translate_xfer_address (CORE_ADDR memaddr, int nr_bytes, |
1039 | 1205 | CORE_ADDR *targ_addr, int *targ_len) |
1040 | 1206 | { |
1041 | - CORE_ADDR phys; | |
1042 | - CORE_ADDR seg; | |
1043 | - CORE_ADDR off; | |
1044 | - char *from = "unknown"; | |
1045 | - char *to = "unknown"; | |
1046 | - | |
1047 | - /* GDB interprets addresses as: | |
1048 | - | |
1049 | - 0x00xxxxxx: Physical unified memory segment (Unified memory) | |
1050 | - 0x01xxxxxx: Physical instruction memory segment (On-chip insn memory) | |
1051 | - 0x02xxxxxx: Physical data memory segment (On-chip data memory) | |
1052 | - 0x10xxxxxx: Logical data address segment (DMAP translated memory) | |
1053 | - 0x11xxxxxx: Logical instruction address segment (IMAP translated memory) | |
1054 | - | |
1055 | - The remote d10v board interprets addresses as: | |
1056 | - | |
1057 | - 0x00xxxxxx: Physical unified memory segment (Unified memory) | |
1058 | - 0x01xxxxxx: Physical instruction memory segment (On-chip insn memory) | |
1059 | - 0x02xxxxxx: Physical data memory segment (On-chip data memory) | |
1060 | - | |
1061 | - Translate according to current IMAP/dmap registers */ | |
1062 | - | |
1063 | - enum | |
1064 | - { | |
1065 | - targ_unified = 0x00000000, | |
1066 | - targ_insn = 0x01000000, | |
1067 | - targ_data = 0x02000000, | |
1068 | - }; | |
1069 | - | |
1070 | - seg = (memaddr >> 24); | |
1071 | - off = (memaddr & 0xffffffL); | |
1072 | - | |
1073 | - switch (seg) | |
1074 | - { | |
1075 | - case 0x00: /* Physical unified memory */ | |
1076 | - from = "phys-unified"; | |
1077 | - phys = targ_unified | off; | |
1078 | - to = "unified"; | |
1079 | - break; | |
1080 | - | |
1081 | - case 0x01: /* Physical instruction memory */ | |
1082 | - from = "phys-insn"; | |
1083 | - phys = targ_insn | off; | |
1084 | - to = "chip-insn"; | |
1085 | - break; | |
1086 | - | |
1087 | - case 0x02: /* Physical data memory segment */ | |
1088 | - from = "phys-data"; | |
1089 | - phys = targ_data | off; | |
1090 | - to = "chip-data"; | |
1091 | - break; | |
1092 | - | |
1093 | - case 0x10: /* in logical data address segment */ | |
1094 | - { | |
1095 | - from = "logical-data"; | |
1096 | - if (off <= 0x7fffL) | |
1097 | - { | |
1098 | - /* On chip data */ | |
1099 | - phys = targ_data + off; | |
1100 | - if (off + nr_bytes > 0x7fffL) | |
1101 | - /* don't cross VM boundary */ | |
1102 | - nr_bytes = 0x7fffL - off + 1; | |
1103 | - to = "chip-data"; | |
1104 | - } | |
1105 | - else if (off <= 0xbfffL) | |
1106 | - { | |
1107 | - unsigned short dmap = read_register (DMAP_REGNUM); | |
1108 | - short map = dmap; | |
1109 | - | |
1110 | - if (map & 0x1000) | |
1111 | - { | |
1112 | - /* Instruction memory */ | |
1113 | - phys = targ_insn | ((map & 0xf) << 14) | (off & 0x3fff); | |
1114 | - to = "chip-insn"; | |
1115 | - } | |
1116 | - else | |
1117 | - { | |
1118 | - /* Unified memory */ | |
1119 | - phys = targ_unified | ((map & 0x3ff) << 14) | (off & 0x3fff); | |
1120 | - to = "unified"; | |
1121 | - } | |
1122 | - if (off + nr_bytes > 0xbfffL) | |
1123 | - /* don't cross VM boundary */ | |
1124 | - nr_bytes = (0xbfffL - off + 1); | |
1125 | - } | |
1126 | - else | |
1127 | - { | |
1128 | - /* Logical address out side of data segments, not supported */ | |
1129 | - *targ_len = 0; | |
1130 | - return; | |
1131 | - } | |
1132 | - break; | |
1133 | - } | |
1134 | - | |
1135 | - case 0x11: /* in logical instruction address segment */ | |
1136 | - { | |
1137 | - short map; | |
1138 | - unsigned short imap0 = read_register (IMAP0_REGNUM); | |
1139 | - unsigned short imap1 = read_register (IMAP1_REGNUM); | |
1140 | - | |
1141 | - from = "logical-insn"; | |
1142 | - if (off <= 0x1ffffL) | |
1143 | - { | |
1144 | - map = imap0; | |
1145 | - } | |
1146 | - else if (off <= 0x3ffffL) | |
1147 | - { | |
1148 | - map = imap1; | |
1149 | - } | |
1150 | - else | |
1151 | - { | |
1152 | - /* Logical address outside of IMAP[01] segment, not | |
1153 | - supported */ | |
1154 | - *targ_len = 0; | |
1155 | - return; | |
1156 | - } | |
1157 | - if ((off & 0x1ffff) + nr_bytes > 0x1ffffL) | |
1158 | - { | |
1159 | - /* don't cross VM boundary */ | |
1160 | - nr_bytes = 0x1ffffL - (off & 0x1ffffL) + 1; | |
1161 | - } | |
1162 | - if (map & 0x1000) | |
1163 | - /* Instruction memory */ | |
1164 | - { | |
1165 | - phys = targ_insn | off; | |
1166 | - to = "chip-insn"; | |
1167 | - } | |
1168 | - else | |
1169 | - { | |
1170 | - phys = ((map & 0x7fL) << 17) + (off & 0x1ffffL); | |
1171 | - if (phys > 0xffffffL) | |
1172 | - { | |
1173 | - /* Address outside of unified address segment */ | |
1174 | - *targ_len = 0; | |
1175 | - return; | |
1176 | - } | |
1177 | - phys |= targ_unified; | |
1178 | - to = "unified"; | |
1179 | - } | |
1180 | - break; | |
1181 | - } | |
1182 | - | |
1183 | - default: | |
1184 | - *targ_len = 0; | |
1185 | - return; | |
1186 | - } | |
1187 | - | |
1188 | - *targ_addr = phys; | |
1189 | - *targ_len = nr_bytes; | |
1207 | + long out_addr; | |
1208 | + long out_len; | |
1209 | + out_len = sim_d10v_translate_addr (memaddr, nr_bytes, | |
1210 | + &out_addr, | |
1211 | + d10v_dmap_register, | |
1212 | + d10v_imap_register); | |
1213 | + *targ_addr = out_addr; | |
1214 | + *targ_len = out_len; | |
1190 | 1215 | } |
1191 | 1216 | |
1217 | + | |
1192 | 1218 | /* The following code implements access to, and display of, the D10V's |
1193 | 1219 | instruction trace buffer. The buffer consists of 64K or more |
1194 | 1220 | 4-byte words of data, of which each words includes an 8-bit count, |
@@ -1490,6 +1516,7 @@ display_trace (low, high) | ||
1490 | 1516 | |
1491 | 1517 | |
1492 | 1518 | static gdbarch_init_ftype d10v_gdbarch_init; |
1519 | + | |
1493 | 1520 | static struct gdbarch * |
1494 | 1521 | d10v_gdbarch_init (info, arches) |
1495 | 1522 | struct gdbarch_info info; |
@@ -1498,12 +1525,42 @@ d10v_gdbarch_init (info, arches) | ||
1498 | 1525 | static LONGEST d10v_call_dummy_words[] = |
1499 | 1526 | {0}; |
1500 | 1527 | struct gdbarch *gdbarch; |
1501 | - int d10v_num_regs = 37; | |
1528 | + int d10v_num_regs; | |
1529 | + struct gdbarch_tdep *tdep; | |
1530 | + gdbarch_register_name_ftype *d10v_register_name; | |
1502 | 1531 | |
1503 | - /* there is only one d10v architecture */ | |
1532 | + /* Find a candidate among the list of pre-declared architectures. */ | |
1533 | + arches = gdbarch_list_lookup_by_info (arches, &info); | |
1504 | 1534 | if (arches != NULL) |
1505 | 1535 | return arches->gdbarch; |
1506 | - gdbarch = gdbarch_alloc (&info, NULL); | |
1536 | + | |
1537 | + /* None found, create a new architecture from the information | |
1538 | + provided. */ | |
1539 | + tdep = XMALLOC (struct gdbarch_tdep); | |
1540 | + gdbarch = gdbarch_alloc (&info, tdep); | |
1541 | + | |
1542 | + switch (info.bfd_arch_info->mach) | |
1543 | + { | |
1544 | + case bfd_mach_d10v_ts2: | |
1545 | + d10v_num_regs = 37; | |
1546 | + d10v_register_name = d10v_ts2_register_name; | |
1547 | + tdep->a0_regnum = TS2_A0_REGNUM; | |
1548 | + tdep->nr_dmap_regs = TS2_NR_DMAP_REGS; | |
1549 | + tdep->register_sim_regno = d10v_ts2_register_sim_regno; | |
1550 | + tdep->dmap_register = d10v_ts2_dmap_register; | |
1551 | + tdep->imap_register = d10v_ts2_imap_register; | |
1552 | + break; | |
1553 | + default: | |
1554 | + case bfd_mach_d10v_ts3: | |
1555 | + d10v_num_regs = 42; | |
1556 | + d10v_register_name = d10v_ts3_register_name; | |
1557 | + tdep->a0_regnum = TS3_A0_REGNUM; | |
1558 | + tdep->nr_dmap_regs = TS3_NR_DMAP_REGS; | |
1559 | + tdep->register_sim_regno = d10v_ts3_register_sim_regno; | |
1560 | + tdep->dmap_register = d10v_ts3_dmap_register; | |
1561 | + tdep->imap_register = d10v_ts3_imap_register; | |
1562 | + break; | |
1563 | + } | |
1507 | 1564 | |
1508 | 1565 | set_gdbarch_read_pc (gdbarch, d10v_read_pc); |
1509 | 1566 | set_gdbarch_write_pc (gdbarch, d10v_write_pc); |
@@ -409,7 +409,8 @@ extern void set_gdb_file_isatty (struct gdb_file *stream, gdb_file_isatty_ftype | ||
409 | 409 | typedef void (gdb_file_rewind_ftype) (struct gdb_file * stream); |
410 | 410 | extern void set_gdb_file_rewind (struct gdb_file *stream, gdb_file_rewind_ftype * rewind); |
411 | 411 | |
412 | -typedef void (gdb_file_put_ftype) (struct gdb_file * stream, struct gdb_file * dest); | |
412 | +typedef void (gdb_file_put_method_ftype) (void *object, const char *buffer, long length_buffer); | |
413 | +typedef void (gdb_file_put_ftype) (struct gdb_file *stream, gdb_file_put_method_ftype * method, void *context); | |
413 | 414 | extern void set_gdb_file_put (struct gdb_file *stream, gdb_file_put_ftype * put); |
414 | 415 | |
415 | 416 | typedef void (gdb_file_delete_ftype) (struct gdb_file * stream); |
@@ -439,7 +440,13 @@ extern int gdb_file_isatty (GDB_FILE *); | ||
439 | 440 | extern void gdb_file_write (struct gdb_file *file, const char *buf, long length_buf); |
440 | 441 | |
441 | 442 | /* NOTE: copies left to right */ |
442 | -extern void gdb_file_put (struct gdb_file *src, struct gdb_file *dest); | |
443 | +extern void gdb_file_put (struct gdb_file *src, gdb_file_put_method_ftype *write, void *dest); | |
444 | + | |
445 | +/* Returns a freshly allocated buffer containing the entire contents | |
446 | + of FILE (as determined by gdb_file_put()) with a NUL character | |
447 | + appended. LENGTH is set to the size of the buffer minus that | |
448 | + appended NUL. */ | |
449 | +extern char *gdb_file_xstrdup (struct gdb_file *file, long *length); | |
443 | 450 | |
444 | 451 | /* More generic printf like operations */ |
445 | 452 |
@@ -782,6 +789,14 @@ enum val_prettyprint | ||
782 | 789 | #define LONG_MAX ((long)(ULONG_MAX >> 1)) /* 0x7FFFFFFF for 32-bits */ |
783 | 790 | #endif |
784 | 791 | |
792 | +#if !defined (ULONGEST_MAX) | |
793 | +#define ULONGEST_MAX (~(ULONGEST)0) /* 0xFFFFFFFFFFFFFFFF for 32-bits */ | |
794 | +#endif | |
795 | + | |
796 | +#if !defined (LONGEST_MAX) /* 0x7FFFFFFFFFFFFFFF for 32-bits */ | |
797 | +#define LONGEST_MAX ((LONGEST)(ULONGEST_MAX >> 1)) | |
798 | +#endif | |
799 | + | |
785 | 800 | /* Convert a LONGEST to an int. This is used in contexts (e.g. number of |
786 | 801 | arguments to a function, number in a value history, register number, etc.) |
787 | 802 | where the value must not be larger than can fit in an int. */ |
@@ -823,16 +838,23 @@ extern char *quit_pre_print; | ||
823 | 838 | |
824 | 839 | extern char *warning_pre_print; |
825 | 840 | |
826 | -extern NORETURN void error (const char *, ...) ATTR_NORETURN; | |
841 | +extern NORETURN void verror (const char *fmt, va_list ap) ATTR_NORETURN; | |
827 | 842 | |
828 | -extern void error_begin (void); | |
843 | +extern NORETURN void error (const char *fmt, ...) ATTR_NORETURN; | |
829 | 844 | |
830 | -extern NORETURN void internal_error (char *, ...) ATTR_NORETURN; | |
845 | +/* DEPRECATED: Use error(), verror() or error_stream(). */ | |
846 | +extern NORETURN void error_begin (void); | |
831 | 847 | |
832 | 848 | extern NORETURN void error_stream (GDB_FILE *) ATTR_NORETURN; |
833 | 849 | |
850 | +/* Returns a freshly allocate buffer containing the last error | |
851 | + message. */ | |
834 | 852 | extern char *error_last_message (void); |
835 | 853 | |
854 | +extern NORETURN void internal_verror (const char *, va_list ap) ATTR_NORETURN; | |
855 | + | |
856 | +extern NORETURN void internal_error (char *, ...) ATTR_NORETURN; | |
857 | + | |
836 | 858 | extern NORETURN void nomem (long) ATTR_NORETURN; |
837 | 859 | |
838 | 860 | /* Reasons for calling return_to_top_level. */ |
@@ -198,7 +198,7 @@ exec_file_attach (args, from_tty) | ||
198 | 198 | {; |
199 | 199 | } |
200 | 200 | if (*argv == NULL) |
201 | - error ("no exec file name was specified"); | |
201 | + error ("No executable file name was specified"); | |
202 | 202 | |
203 | 203 | filename = tilde_expand (*argv); |
204 | 204 | make_cleanup (free, filename); |
@@ -369,13 +369,6 @@ write_inferior_memory (memaddr, myaddr, len) | ||
369 | 369 | } |
370 | 370 | |
371 | 371 | void |
372 | -initialize () | |
372 | +initialize_low () | |
373 | 373 | { |
374 | - inferior_pid = 0; | |
375 | -} | |
376 | - | |
377 | -int | |
378 | -have_inferior_p () | |
379 | -{ | |
380 | - return inferior_pid != 0; | |
381 | 374 | } |
@@ -451,6 +451,15 @@ static int u_offsets[] = | ||
451 | 451 | PT_F125, |
452 | 452 | PT_F126, |
453 | 453 | PT_F127, |
454 | + /* predicate registers - we don't fetch these individually */ | |
455 | + -1, -1, -1, -1, -1, -1, -1, -1, | |
456 | + -1, -1, -1, -1, -1, -1, -1, -1, | |
457 | + -1, -1, -1, -1, -1, -1, -1, -1, | |
458 | + -1, -1, -1, -1, -1, -1, -1, -1, | |
459 | + -1, -1, -1, -1, -1, -1, -1, -1, | |
460 | + -1, -1, -1, -1, -1, -1, -1, -1, | |
461 | + -1, -1, -1, -1, -1, -1, -1, -1, | |
462 | + -1, -1, -1, -1, -1, -1, -1, -1, | |
454 | 463 | /* branch registers */ |
455 | 464 | PT_B0, |
456 | 465 | PT_B1, |
@@ -460,6 +469,8 @@ static int u_offsets[] = | ||
460 | 469 | PT_B5, |
461 | 470 | PT_B6, |
462 | 471 | PT_B7, |
472 | + /* virtual frame pointer and virtual return address pointer */ | |
473 | + -1, -1, | |
463 | 474 | /* other registers */ |
464 | 475 | PT_PR, |
465 | 476 | PT_CR_IIP, |
@@ -735,14 +746,7 @@ write_inferior_memory (memaddr, myaddr, len) | ||
735 | 746 | } |
736 | 747 | |
737 | 748 | void |
738 | -initialize () | |
749 | +initialize_low () | |
739 | 750 | { |
740 | - inferior_pid = 0; | |
741 | 751 | initialize_arch(); |
742 | 752 | } |
743 | - | |
744 | -int | |
745 | -have_inferior_p () | |
746 | -{ | |
747 | - return inferior_pid != 0; | |
748 | -} |
@@ -746,3 +746,8 @@ ptrace (PTRACE_POKETEXT): errno=%d, pid=0x%x, addr=0x%x, buffer[i] = 0x%x\n", | ||
746 | 746 | |
747 | 747 | return 0; |
748 | 748 | } |
749 | + | |
750 | +void | |
751 | +initialize_low () | |
752 | +{ | |
753 | +} |
@@ -276,16 +276,7 @@ write_inferior_memory (memaddr, myaddr, len) | ||
276 | 276 | return 0; |
277 | 277 | } |
278 | 278 | |
279 | -#if 0 | |
280 | 279 | void |
281 | -initialize () | |
282 | -{ | |
283 | - inferior_pid = 0; | |
284 | -} | |
285 | - | |
286 | -int | |
287 | -have_inferior_p () | |
280 | +initialize_low () | |
288 | 281 | { |
289 | - return inferior_pid != 0; | |
290 | 282 | } |
291 | -#endif |
@@ -324,13 +324,6 @@ write_inferior_memory (memaddr, myaddr, len) | ||
324 | 324 | } |
325 | 325 | |
326 | 326 | void |
327 | -initialize () | |
327 | +initialize_low () | |
328 | 328 | { |
329 | - inferior_pid = 0; | |
330 | -} | |
331 | - | |
332 | -int | |
333 | -have_inferior_p () | |
334 | -{ | |
335 | - return inferior_pid != 0; | |
336 | 329 | } |
@@ -303,13 +303,6 @@ write_inferior_memory (memaddr, myaddr, len) | ||
303 | 303 | } |
304 | 304 | |
305 | 305 | void |
306 | -initialize () | |
306 | +initialize_low () | |
307 | 307 | { |
308 | - inferior_pid = 0; | |
309 | -} | |
310 | - | |
311 | -int | |
312 | -have_inferior_p () | |
313 | -{ | |
314 | - return inferior_pid != 0; | |
315 | 308 | } |
@@ -62,6 +62,8 @@ main (argc, argv) | ||
62 | 62 | if (argc < 3) |
63 | 63 | error ("Usage: gdbserver tty prog [args ...]"); |
64 | 64 | |
65 | + initialize_low (); | |
66 | + | |
65 | 67 | /* Wait till we are at first instruction in program. */ |
66 | 68 | signal = start_inferior (&argv[2], &status); |
67 | 69 |
@@ -33,6 +33,7 @@ unsigned char mywait PARAMS ((char *status)); | ||
33 | 33 | void read_inferior_memory PARAMS ((CORE_ADDR memaddr, char *myaddr, int len)); |
34 | 34 | int write_inferior_memory PARAMS ((CORE_ADDR memaddr, char *myaddr, int len)); |
35 | 35 | int create_inferior (); |
36 | +void initialize_low (); | |
36 | 37 | |
37 | 38 | /* Target-specific variables */ |
38 | 39 |
@@ -345,7 +345,7 @@ sig_map[] = | ||
345 | 345 | 4, TARGET_SIGNAL_FPE, |
346 | 346 | 5, TARGET_SIGNAL_SEGV, |
347 | 347 | 6, TARGET_SIGNAL_ILL, |
348 | - 7, TARGET_SIGNAL_FPE, | |
348 | + 7, TARGET_SIGNAL_EMT, /* no-coprocessor exception */ | |
349 | 349 | 8, TARGET_SIGNAL_SEGV, |
350 | 350 | 9, TARGET_SIGNAL_SEGV, |
351 | 351 | 10, TARGET_SIGNAL_BUS, |
@@ -570,7 +570,8 @@ go32_fetch_registers (int regno) | ||
570 | 570 | supply_register (regno, |
571 | 571 | (char *) &npx + regno_mapping[regno].tss_ofs); |
572 | 572 | else |
573 | - fatal ("Invalid register no. %d in go32_fetch_register.", regno); | |
573 | + internal_error ("Invalid register no. %d in go32_fetch_register.", | |
574 | + regno); | |
574 | 575 | } |
575 | 576 | } |
576 | 577 |
@@ -587,7 +588,7 @@ store_register (int regno) | ||
587 | 588 | else if (regno < 31) |
588 | 589 | rp = (char *) &npx + regno_mapping[regno].tss_ofs; |
589 | 590 | else |
590 | - fatal ("Invalid register no. %d in store_register.", regno); | |
591 | + internal_error ("Invalid register no. %d in store_register.", regno); | |
591 | 592 | memcpy (rp, v, regno_mapping[regno].size); |
592 | 593 | } |
593 | 594 |
@@ -680,7 +681,7 @@ go32_create_inferior (char *exec_file, char *args, char **env) | ||
680 | 681 | resume_is_step = 0; |
681 | 682 | /* Init command line storage. */ |
682 | 683 | if (redir_debug_init (&child_cmd) == -1) |
683 | - fatal ("Cannot allocate redirection storage: not enough memory.\n"); | |
684 | + internal_error ("Cannot allocate redirection storage: not enough memory.\n"); | |
684 | 685 | |
685 | 686 | /* Parse the command line and create redirections. */ |
686 | 687 | if (strpbrk (args, "<>")) |
@@ -1311,7 +1312,7 @@ init_go32_ops (void) | ||
1311 | 1312 | |
1312 | 1313 | /* Initialize child's command line storage. */ |
1313 | 1314 | if (redir_debug_init (&child_cmd) == -1) |
1314 | - fatal ("Cannot allocate redirection storage: not enough memory.\n"); | |
1315 | + internal_error ("Cannot allocate redirection storage: not enough memory.\n"); | |
1315 | 1316 | } |
1316 | 1317 | |
1317 | 1318 | void |
@@ -2230,7 +2230,7 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p) | ||
2230 | 2230 | |
2231 | 2231 | funsymbol = lookup_minimal_symbol_by_pc (fun); |
2232 | 2232 | if (!funsymbol) |
2233 | - error ("Unable to find minimal symbol for target fucntion.\n"); | |
2233 | + error ("Unable to find minimal symbol for target function.\n"); | |
2234 | 2234 | |
2235 | 2235 | /* Search all the object files for an import symbol with the |
2236 | 2236 | right name. */ |
@@ -983,7 +983,7 @@ info_sharedlibrary_command (ignore, from_tty) | ||
983 | 983 | |
984 | 984 | if (exec_bfd == NULL) |
985 | 985 | { |
986 | - printf_unfiltered ("No exec file.\n"); | |
986 | + printf_unfiltered ("No executable file.\n"); | |
987 | 987 | return; |
988 | 988 | } |
989 | 989 | while ((so = find_solib (so)) != NULL) |
@@ -912,6 +912,7 @@ monitor_supply_register (regno, valstr) | ||
912 | 912 | unsigned char regbuf[MAX_REGISTER_RAW_SIZE]; |
913 | 913 | char *p; |
914 | 914 | |
915 | + val = 0; | |
915 | 916 | p = valstr; |
916 | 917 | while (p && *p != '\0') |
917 | 918 | { |
@@ -732,7 +732,7 @@ info_sharedlibrary_command (ignore, from_tty) | ||
732 | 732 | |
733 | 733 | if (exec_bfd == NULL) |
734 | 734 | { |
735 | - printf_unfiltered ("No exec file.\n"); | |
735 | + printf_unfiltered ("No executable file.\n"); | |
736 | 736 | return; |
737 | 737 | } |
738 | 738 | while ((so = find_solib (so)) != NULL) |
@@ -794,7 +794,7 @@ pa64_sharedlibrary_info_command (ignore, from_tty) | ||
794 | 794 | |
795 | 795 | if (exec_bfd == NULL) |
796 | 796 | { |
797 | - printf_unfiltered ("no exec file.\n"); | |
797 | + printf_unfiltered ("No executable file.\n"); | |
798 | 798 | return; |
799 | 799 | } |
800 | 800 |
@@ -108,13 +108,13 @@ static int max_load_size; | ||
108 | 108 | static int execute_status; |
109 | 109 | |
110 | 110 | /* Send heatbeat packets? */ |
111 | -static int rdi_heartbeat = 0; | |
111 | +static int rdi_heartbeat = 0; | |
112 | 112 | |
113 | 113 | /* Target has ROM at address 0. */ |
114 | 114 | static int rom_at_zero = 0; |
115 | 115 | |
116 | 116 | /* Enable logging? */ |
117 | -static int log_enable = 0; | |
117 | +static int log_enable = 0; | |
118 | 118 | |
119 | 119 | /* Name of the log file. Default is "rdi.log". */ |
120 | 120 | static char *log_filename; |
@@ -236,8 +236,8 @@ device is attached to the remote system (e.g. /dev/ttya)."); | ||
236 | 236 | |
237 | 237 | /* split name after whitespace, pass tail as arg to open command */ |
238 | 238 | |
239 | - devName = strdup(name); | |
240 | - p = strchr(devName,' '); | |
239 | + devName = strdup (name); | |
240 | + p = strchr (devName, ' '); | |
241 | 241 | if (p) |
242 | 242 | { |
243 | 243 | *p = '\0'; |
@@ -280,7 +280,7 @@ device is attached to the remote system (e.g. /dev/ttya)."); | ||
280 | 280 | { |
281 | 281 | printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt)); |
282 | 282 | Adp_CloseDevice (); |
283 | - error("RID_open failed\n"); | |
283 | + error ("RID_open failed\n"); | |
284 | 284 | } |
285 | 285 | |
286 | 286 | rslt = angel_RDI_info (RDIInfo_Target, &arg1, &arg2); |
@@ -999,47 +999,49 @@ Specify the serial device it is connected to (e.g. /dev/ttya)."; | ||
999 | 999 | arm_rdi_ops.to_magic = OPS_MAGIC; |
1000 | 1000 | } |
1001 | 1001 | |
1002 | -static void rdilogfile_command (char *arg, int from_tty) | |
1002 | +static void | |
1003 | +rdilogfile_command (char *arg, int from_tty) | |
1003 | 1004 | { |
1004 | 1005 | if (!arg || strlen (arg) == 0) |
1005 | 1006 | { |
1006 | 1007 | printf_filtered ("rdi log file is '%s'\n", log_filename); |
1007 | 1008 | return; |
1008 | 1009 | } |
1009 | - | |
1010 | + | |
1010 | 1011 | if (log_filename) |
1011 | 1012 | free (log_filename); |
1012 | - | |
1013 | + | |
1013 | 1014 | log_filename = strdup (arg); |
1014 | 1015 | |
1015 | 1016 | Adp_SetLogfile (log_filename); |
1016 | 1017 | } |
1017 | 1018 | |
1018 | -static void rdilogenable_command (char *args, int from_tty) | |
1019 | +static void | |
1020 | +rdilogenable_command (char *args, int from_tty) | |
1019 | 1021 | { |
1020 | 1022 | if (!args || strlen (args) == 0) |
1021 | 1023 | { |
1022 | 1024 | printf_filtered ("rdi log is %s\n", log_enable ? "enabled" : "disabled"); |
1023 | 1025 | return; |
1024 | 1026 | } |
1025 | - | |
1026 | - if (!strcasecmp (args,"1") || | |
1027 | - !strcasecmp (args,"y") || | |
1028 | - !strcasecmp (args,"yes") || | |
1029 | - !strcasecmp (args,"on") || | |
1030 | - !strcasecmp (args,"t") || | |
1031 | - !strcasecmp (args,"true")) | |
1032 | - Adp_SetLogEnable (log_enable=1); | |
1033 | - else if (!strcasecmp (args,"0") || | |
1034 | - !strcasecmp (args,"n") || | |
1035 | - !strcasecmp (args,"no") || | |
1036 | - !strcasecmp (args,"off") || | |
1037 | - !strcasecmp (args,"f") || | |
1038 | - !strcasecmp (args,"false")) | |
1039 | - Adp_SetLogEnable (log_enable=0); | |
1027 | + | |
1028 | + if (!strcasecmp (args, "1") || | |
1029 | + !strcasecmp (args, "y") || | |
1030 | + !strcasecmp (args, "yes") || | |
1031 | + !strcasecmp (args, "on") || | |
1032 | + !strcasecmp (args, "t") || | |
1033 | + !strcasecmp (args, "true")) | |
1034 | + Adp_SetLogEnable (log_enable = 1); | |
1035 | + else if (!strcasecmp (args, "0") || | |
1036 | + !strcasecmp (args, "n") || | |
1037 | + !strcasecmp (args, "no") || | |
1038 | + !strcasecmp (args, "off") || | |
1039 | + !strcasecmp (args, "f") || | |
1040 | + !strcasecmp (args, "false")) | |
1041 | + Adp_SetLogEnable (log_enable = 0); | |
1040 | 1042 | else |
1041 | 1043 | printf_filtered ("rdilogenable: unrecognized argument '%s'\n" |
1042 | - " try y or n\n",args); | |
1044 | + " try y or n\n", args); | |
1043 | 1045 | } |
1044 | 1046 | |
1045 | 1047 | void |
@@ -1048,9 +1050,9 @@ _initialize_remote_rdi () | ||
1048 | 1050 | init_rdi_ops (); |
1049 | 1051 | add_target (&arm_rdi_ops); |
1050 | 1052 | |
1051 | - log_filename = strdup("rdi.log"); | |
1052 | - Adp_SetLogfile(log_filename); | |
1053 | - Adp_SetLogEnable(log_enable); | |
1053 | + log_filename = strdup ("rdi.log"); | |
1054 | + Adp_SetLogfile (log_filename); | |
1055 | + Adp_SetLogEnable (log_enable); | |
1054 | 1056 | |
1055 | 1057 | add_cmd ("rdilogfile", class_maintenance, |
1056 | 1058 | rdilogfile_command, |
@@ -1061,7 +1063,7 @@ Without an argument, shows the current logfile name.\n\ | ||
1061 | 1063 | See also: rdilogenable\n", |
1062 | 1064 | &maintenancelist); |
1063 | 1065 | |
1064 | - add_cmd("rdilogenable", class_maintenance, | |
1066 | + add_cmd ("rdilogenable", class_maintenance, | |
1065 | 1067 | rdilogenable_command, |
1066 | 1068 | "Set enable logging of ADP packets.\n\ |
1067 | 1069 | This will log ADP packets exchanged between gdb and the\n\ |
@@ -1078,7 +1080,7 @@ Withough an argument, it will display current state.\n", | ||
1078 | 1080 | A true value disables vector catching, false enables vector catching.\n\ |
1079 | 1081 | This is evaluated at the time the 'target rdi' command is executed\n", |
1080 | 1082 | &setlist), |
1081 | - &showlist); | |
1083 | + &showlist); | |
1082 | 1084 | |
1083 | 1085 | add_show_from_set |
1084 | 1086 | (add_set_cmd ("rdiheartbeat", no_class, |
@@ -1088,7 +1090,7 @@ I don't know why you would want this. If you enable them,\n\ | ||
1088 | 1090 | it will confuse ARM and EPI JTAG interface boxes as well\n\ |
1089 | 1091 | as the Angel Monitor.\n", |
1090 | 1092 | &setlist), |
1091 | - &showlist); | |
1093 | + &showlist); | |
1092 | 1094 | } |
1093 | 1095 | |
1094 | 1096 | /* A little dummy to make linking with the library succeed. */ |
@@ -194,12 +194,7 @@ gdb_os_write_stdout (p, buf, len) | ||
194 | 194 | int i; |
195 | 195 | char b[2]; |
196 | 196 | |
197 | - for (i = 0; i < len; i++) | |
198 | - { | |
199 | - b[0] = buf[i]; | |
200 | - b[1] = 0; | |
201 | - fputs_unfiltered (b, gdb_stdtarg); | |
202 | - } | |
197 | + gdb_file_write (gdb_stdtarg, buf, len); | |
203 | 198 | return len; |
204 | 199 | } |
205 | 200 |
@@ -209,7 +204,7 @@ static void | ||
209 | 204 | gdb_os_flush_stdout (p) |
210 | 205 | host_callback *p; |
211 | 206 | { |
212 | - gdb_flush (gdb_stdout); | |
207 | + gdb_flush (gdb_stdtarg); | |
213 | 208 | } |
214 | 209 | |
215 | 210 | /* GDB version of os_write_stderr callback. */ |
@@ -281,12 +276,8 @@ gdb_os_error (host_callback * p, const char *format,...) | ||
281 | 276 | { |
282 | 277 | va_list args; |
283 | 278 | va_start (args, format); |
284 | - | |
285 | - error_begin (); | |
286 | - vfprintf_filtered (gdb_stderr, format, args); | |
287 | - fprintf_filtered (gdb_stderr, "\n"); | |
279 | + verror (format, args); | |
288 | 280 | va_end (args); |
289 | - return_to_top_level (RETURN_ERROR); | |
290 | 281 | } |
291 | 282 | } |
292 | 283 |
@@ -1493,7 +1493,6 @@ info_cb (th, s) | ||
1493 | 1493 | { |
1494 | 1494 | td_err_e ret; |
1495 | 1495 | td_thrinfo_t ti; |
1496 | - struct minimal_symbol *msym; | |
1497 | 1496 | |
1498 | 1497 | if ((ret = p_td_thr_get_info (th, &ti)) == TD_OK) |
1499 | 1498 | { |
@@ -1527,17 +1526,25 @@ info_cb (th, s) | ||
1527 | 1526 | } |
1528 | 1527 | /* Print thr_create start function: */ |
1529 | 1528 | if (ti.ti_startfunc != 0) |
1530 | - if (msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc)) | |
1531 | - printf_filtered (" startfunc: %s\n", SYMBOL_NAME (msym)); | |
1532 | - else | |
1533 | - printf_filtered (" startfunc: 0x%08x\n", ti.ti_startfunc); | |
1529 | + { | |
1530 | + struct minimal_symbol *msym; | |
1531 | + msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc); | |
1532 | + if (msym) | |
1533 | + printf_filtered (" startfunc: %s\n", SYMBOL_NAME (msym)); | |
1534 | + else | |
1535 | + printf_filtered (" startfunc: 0x%s\n", paddr (ti.ti_startfunc)); | |
1536 | + } | |
1534 | 1537 | |
1535 | 1538 | /* If thread is asleep, print function that went to sleep: */ |
1536 | 1539 | if (ti.ti_state == TD_THR_SLEEP) |
1537 | - if (msym = lookup_minimal_symbol_by_pc (ti.ti_pc)) | |
1538 | - printf_filtered (" - Sleep func: %s\n", SYMBOL_NAME (msym)); | |
1539 | - else | |
1540 | - printf_filtered (" - Sleep func: 0x%08x\n", ti.ti_startfunc); | |
1540 | + { | |
1541 | + struct minimal_symbol *msym; | |
1542 | + msym = lookup_minimal_symbol_by_pc (ti.ti_pc); | |
1543 | + if (msym) | |
1544 | + printf_filtered (" - Sleep func: %s\n", SYMBOL_NAME (msym)); | |
1545 | + else | |
1546 | + printf_filtered (" - Sleep func: 0x%s\n", paddr (ti.ti_startfunc)); | |
1547 | + } | |
1541 | 1548 | |
1542 | 1549 | /* Wrap up line, if necessary */ |
1543 | 1550 | if (ti.ti_state != TD_THR_SLEEP && ti.ti_startfunc == 0) |
@@ -1277,7 +1277,7 @@ info_sharedlibrary_command (ignore, from_tty) | ||
1277 | 1277 | |
1278 | 1278 | if (exec_bfd == NULL) |
1279 | 1279 | { |
1280 | - printf_unfiltered ("No exec file.\n"); | |
1280 | + printf_unfiltered ("No executable file.\n"); | |
1281 | 1281 | return; |
1282 | 1282 | } |
1283 | 1283 |
@@ -1445,7 +1445,7 @@ som_sharedlibrary_info_command (ignore, from_tty) | ||
1445 | 1445 | |
1446 | 1446 | if (exec_bfd == NULL) |
1447 | 1447 | { |
1448 | - printf_unfiltered ("no exec file.\n"); | |
1448 | + printf_unfiltered ("No executable file.\n"); | |
1449 | 1449 | return; |
1450 | 1450 | } |
1451 | 1451 |
@@ -91,7 +91,7 @@ static char * | ||
91 | 91 | static struct type * |
92 | 92 | dbx_alloc_type PARAMS ((int[2], struct objfile *)); |
93 | 93 | |
94 | -static long read_huge_number PARAMS ((char **, int, int *)); | |
94 | +static LONGEST read_huge_number PARAMS ((char **, int, int *)); | |
95 | 95 | |
96 | 96 | static struct type *error_type PARAMS ((char **, struct objfile *)); |
97 | 97 |
@@ -4480,7 +4480,7 @@ read_sun_floating_type (pp, typenums, objfile) | ||
4480 | 4480 | |
4481 | 4481 | If encounter garbage, set *BITS to -1 and return 0. */ |
4482 | 4482 | |
4483 | -static long | |
4483 | +static LONGEST | |
4484 | 4484 | read_huge_number (pp, end, bits) |
4485 | 4485 | char **pp; |
4486 | 4486 | int end; |
@@ -4488,12 +4488,12 @@ read_huge_number (pp, end, bits) | ||
4488 | 4488 | { |
4489 | 4489 | char *p = *pp; |
4490 | 4490 | int sign = 1; |
4491 | - long n = 0; | |
4491 | + LONGEST n = 0; | |
4492 | 4492 | int radix = 10; |
4493 | 4493 | char overflow = 0; |
4494 | 4494 | int nbits = 0; |
4495 | 4495 | int c; |
4496 | - long upper_limit; | |
4496 | + LONGEST upper_limit; | |
4497 | 4497 | |
4498 | 4498 | if (*p == '-') |
4499 | 4499 | { |
@@ -4510,9 +4510,9 @@ read_huge_number (pp, end, bits) | ||
4510 | 4510 | } |
4511 | 4511 | |
4512 | 4512 | if (os9k_stabs) |
4513 | - upper_limit = ULONG_MAX / radix; | |
4513 | + upper_limit = ULONGEST_MAX / radix; | |
4514 | 4514 | else |
4515 | - upper_limit = LONG_MAX / radix; | |
4515 | + upper_limit = LONGEST_MAX / radix; | |
4516 | 4516 | |
4517 | 4517 | while ((c = *p++) >= '0' && c < ('0' + radix)) |
4518 | 4518 | { |
@@ -4593,7 +4593,7 @@ read_range_type (pp, typenums, objfile) | ||
4593 | 4593 | { |
4594 | 4594 | char *orig_pp = *pp; |
4595 | 4595 | int rangenums[2]; |
4596 | - long n2, n3; | |
4596 | + LONGEST n2, n3; | |
4597 | 4597 | int n2bits, n3bits; |
4598 | 4598 | int self_subrange; |
4599 | 4599 | struct type *result_type; |
@@ -4646,8 +4646,8 @@ read_range_type (pp, typenums, objfile) | ||
4646 | 4646 | fit in a long but <large number>-1 does. */ |
4647 | 4647 | else if ((n2bits != 0 && n3bits != 0 && n2bits == n3bits + 1) |
4648 | 4648 | || (n2bits != 0 && n3bits == 0 |
4649 | - && (n2bits == sizeof (long) * HOST_CHAR_BIT) | |
4650 | - && n3 == LONG_MAX)) | |
4649 | + && (n2bits == sizeof (LONGEST) * HOST_CHAR_BIT) | |
4650 | + && n3 == LONGEST_MAX)) | |
4651 | 4651 | { |
4652 | 4652 | got_signed = 1; |
4653 | 4653 | nbits = n2bits; |
@@ -1,3 +1,25 @@ | ||
1 | +1999-11-12 Stan Shebs <shebs@andros.cygnus.com> | |
2 | + | |
3 | + * gdb.base/dollar.exp: Remove, now in gdb.hp. | |
4 | + | |
5 | +1999-11-10 Jimmy Guo <guo@cup.hp.com> | |
6 | + | |
7 | + * gdb.exp (get_compiler_info): pick up compiler.c and compiler.cc | |
8 | + from $srcdir/lib/. | |
9 | + * lib/compiler.c, lib/compiler.cc: New files, moved from gdb.base/ | |
10 | + and gdb.c++/. | |
11 | + | |
12 | + * gdb.c++/derivation.exp: remove redundant get compiler info code. | |
13 | + | |
14 | + * gdb.base/commands.exp: add '$gdb_prompt $' anchor to | |
15 | + 'continue with watch' test point. | |
16 | + | |
17 | +1999-11-08 Jim Blandy <jimb@zenia.red-bean.com> | |
18 | + | |
19 | + Merged from p2linux-990323-branch: | |
20 | + | |
21 | + * lib/gdb.exp (gdb_continue_to_breakpoint): New function. | |
22 | + | |
1 | 23 | Mon Nov 8 23:07:09 1999 Andrew Cagney <cagney@amy.cygnus.com> |
2 | 24 | |
3 | 25 | * gdb.base/remote.exp: Test ``set remote memory-write-packet-sized |
@@ -320,7 +320,7 @@ proc watchpoint_command_test {} { | ||
320 | 320 | } |
321 | 321 | send_gdb "continue\n" |
322 | 322 | gdb_expect { |
323 | - -re "Continuing.*\[Ww\]atchpoint $wp_id deleted because the program has left the block in.*which its expression is valid.*run.c:57.*"\ | |
323 | + -re "Continuing.*\[Ww\]atchpoint $wp_id deleted because the program has left the block in.*which its expression is valid.*run.c:57.*$gdb_prompt $"\ | |
324 | 324 | {pass "continue with watch"} |
325 | 325 | -re "$gdb_prompt $"\ |
326 | 326 | {fail "continue with watch"} |
@@ -60,21 +60,6 @@ gdb_exit | ||
60 | 60 | gdb_start |
61 | 61 | gdb_reinitialize_dir $srcdir/$subdir |
62 | 62 | gdb_load ${binfile} |
63 | -remote_file build delete ${binfile}.ci | |
64 | - if {![istarget "hppa*-*-hpux*"]} { | |
65 | - if { [gdb_compile "${srcdir}/${subdir}/compiler.cc" "${binfile}.ci" preprocess ""] != "" | |
66 | -} { | |
67 | - gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will auto | |
68 | -matically fail." | |
69 | - } | |
70 | - } else { | |
71 | - if { [gdb_preprocess "${srcdir}/${subdir}/compiler.cc" "${binfile}.ci" "c++"] != "" } { | |
72 | - perror "Couldn't make ${binfile}.ci file" | |
73 | - return 1; | |
74 | - } | |
75 | - } | |
76 | - | |
77 | -source ${binfile}.ci | |
78 | 63 | |
79 | 64 | # |
80 | 65 | # set it up at a breakpoint so we can play with the variable values |
@@ -0,0 +1,31 @@ | ||
1 | +/* Often the behavior of any particular test depends upon what compiler was | |
2 | + used to compile the test. As each test is compiled, this file is | |
3 | + preprocessed by the same compiler used to compile that specific test | |
4 | + (different tests might be compiled by different compilers, particularly | |
5 | + if compiled at different times), and used to generate a *.ci (compiler | |
6 | + info) file for that test. | |
7 | + | |
8 | + I.E., when callfuncs is compiled, a callfuncs.ci file will be generated, | |
9 | + which can then be sourced by callfuncs.exp to give callfuncs.exp access | |
10 | + to information about the compilation environment. | |
11 | + | |
12 | + TODO: It might be a good idea to add expect code that tests each | |
13 | + definition made with 'set" to see if one already exists, and if so | |
14 | + warn about conflicts if it is being set to something else. */ | |
15 | + | |
16 | +/* This needs to be kept in sync with whatis.c and gdb.exp(get_compiler_info). | |
17 | + If this ends up being hairy, we could use a common header file. */ | |
18 | + | |
19 | +#if defined (__STDC__) || defined (_AIX) | |
20 | +set signed_keyword_not_used 0 | |
21 | +#else | |
22 | +set signed_keyword_not_used 1 | |
23 | +#endif | |
24 | + | |
25 | +#if defined (__GNUC__) | |
26 | +set gcc_compiled __GNUC__ | |
27 | +#else | |
28 | +set gcc_compiled 0 | |
29 | +#endif | |
30 | + | |
31 | +return 0 |
@@ -0,0 +1,34 @@ | ||
1 | +/* Often the behavior of any particular test depends upon what compiler was | |
2 | + used to compile the test. As each test is compiled, this file is | |
3 | + preprocessed by the same compiler used to compile that specific test | |
4 | + (different tests might be compiled by different compilers, particularly | |
5 | + if compiled at different times), and used to generate a *.ci (compiler | |
6 | + info) file for that test. | |
7 | + | |
8 | + I.E., when callfuncs is compiled, a callfuncs.ci file will be generated, | |
9 | + which can then be sourced by callfuncs.exp to give callfuncs.exp access | |
10 | + to information about the compilation environment. | |
11 | + | |
12 | + TODO: It might be a good idea to add expect code that tests each | |
13 | + definition made with 'set" to see if one already exists, and if so | |
14 | + warn about conflicts if it is being set to something else. */ | |
15 | + | |
16 | +#if defined(__GNUC__) && __GNUC__ >= 2 && __GNUC_MINOR__ >= 6 | |
17 | +set supports_template_debugging 1 | |
18 | +#else | |
19 | +set supports_template_debugging 0 | |
20 | +#endif | |
21 | + | |
22 | +#if defined(__cplusplus) | |
23 | +set supports_template_debugging 1 | |
24 | +#else | |
25 | +set supports_template_debugging 0 | |
26 | +#endif | |
27 | + | |
28 | +#if defined (__GNUC__) | |
29 | +set gcc_compiled __GNUC__ | |
30 | +#else | |
31 | +set gcc_compiled 0 | |
32 | +#endif | |
33 | + | |
34 | +return 0 |
@@ -335,6 +335,31 @@ proc runto_main { } { | ||
335 | 335 | } |
336 | 336 | |
337 | 337 | |
338 | +### Continue, and expect to hit a breakpoint. | |
339 | +### Report a pass or fail, depending on whether it seems to have | |
340 | +### worked. Use NAME as part of the test name; each call to | |
341 | +### continue_to_breakpoint should use a NAME which is unique within | |
342 | +### that test file. | |
343 | +proc gdb_continue_to_breakpoint {name} { | |
344 | + global gdb_prompt | |
345 | + set full_name "continue to breakpoint: $name" | |
346 | + | |
347 | + send_gdb "continue\n" | |
348 | + gdb_expect { | |
349 | + -re "Breakpoint .* at .*\r\n$gdb_prompt $" { | |
350 | + pass $full_name | |
351 | + } | |
352 | + -re ".*$gdb_prompt $" { | |
353 | + fail $full_name | |
354 | + } | |
355 | + timeout { | |
356 | + fail "$full_name (timeout)" | |
357 | + } | |
358 | + } | |
359 | +} | |
360 | + | |
361 | + | |
362 | + | |
338 | 363 | # gdb_test COMMAND PATTERN MESSAGE -- send a command to gdb; test the result. |
339 | 364 | # |
340 | 365 | # COMMAND is the command to execute, send to GDB with send_gdb. If |
@@ -901,13 +926,13 @@ proc get_compiler_info {binfile args} { | ||
901 | 926 | if {![istarget "hppa*-*-hpux*"]} { |
902 | 927 | if { [llength $args] > 0 } { |
903 | 928 | if {$args == "c++"} { |
904 | - if { [gdb_compile "${srcdir}/${subdir}/compiler.cc" "${binfile}.ci" preprocess {}] != "" } { | |
929 | + if { [gdb_compile "${srcdir}/lib/compiler.cc" "${binfile}.ci" preprocess {}] != "" } { | |
905 | 930 | perror "Couldn't make ${binfile}.ci file" |
906 | 931 | return 1; |
907 | 932 | } |
908 | 933 | } |
909 | 934 | } else { |
910 | - if { [gdb_compile "${srcdir}/${subdir}/compiler.c" "${binfile}.ci" preprocess {}] != "" } { | |
935 | + if { [gdb_compile "${srcdir}/lib/compiler.c" "${binfile}.ci" preprocess {}] != "" } { | |
911 | 936 | perror "Couldn't make ${binfile}.ci file" |
912 | 937 | return 1; |
913 | 938 | } |
@@ -916,7 +941,7 @@ proc get_compiler_info {binfile args} { | ||
916 | 941 | if { [llength $args] > 0 } { |
917 | 942 | if {$args == "c++"} { |
918 | 943 | if { [eval gdb_preprocess \ |
919 | - [list "${srcdir}/${subdir}/compiler.cc" "${binfile}.ci"] \ | |
944 | + [list "${srcdir}/lib/compiler.cc" "${binfile}.ci"] \ | |
920 | 945 | $args] != "" } { |
921 | 946 | perror "Couldn't make ${binfile}.ci file" |
922 | 947 | return 1; |
@@ -924,7 +949,7 @@ proc get_compiler_info {binfile args} { | ||
924 | 949 | } |
925 | 950 | } elseif { $args != "f77" } { |
926 | 951 | if { [eval gdb_preprocess \ |
927 | - [list "${srcdir}/${subdir}/compiler.c" "${binfile}.ci"] \ | |
952 | + [list "${srcdir}/lib/compiler.c" "${binfile}.ci"] \ | |
928 | 953 | $args] != "" } { |
929 | 954 | perror "Couldn't make ${binfile}.ci file" |
930 | 955 | return 1; |
@@ -523,31 +523,38 @@ error_begin () | ||
523 | 523 | and the remaining args are passed as arguments to it. */ |
524 | 524 | |
525 | 525 | NORETURN void |
526 | +verror (const char *string, va_list args) | |
527 | +{ | |
528 | + /* FIXME: cagney/1999-11-10: All error calls should come here. | |
529 | + Unfortunatly some code uses the sequence: error_begin(); print | |
530 | + error message; return_to_top_level. That code should be | |
531 | + flushed. */ | |
532 | + error_begin (); | |
533 | + vfprintf_filtered (gdb_stderr, string, args); | |
534 | + fprintf_filtered (gdb_stderr, "\n"); | |
535 | + /* Save it as the last error as well (no newline) */ | |
536 | + gdb_file_rewind (gdb_lasterr); | |
537 | + vfprintf_filtered (gdb_lasterr, string, args); | |
538 | + va_end (args); | |
539 | + return_to_top_level (RETURN_ERROR); | |
540 | +} | |
541 | + | |
542 | +NORETURN void | |
526 | 543 | error (const char *string,...) |
527 | 544 | { |
528 | 545 | va_list args; |
529 | 546 | va_start (args, string); |
530 | - if (error_hook) | |
531 | - (*error_hook) (); | |
532 | - else | |
533 | - { | |
534 | - error_begin (); | |
535 | - vfprintf_filtered (gdb_stderr, string, args); | |
536 | - fprintf_filtered (gdb_stderr, "\n"); | |
537 | - /* Save it as the last error as well (no newline) */ | |
538 | - gdb_file_rewind (gdb_lasterr); | |
539 | - vfprintf_filtered (gdb_lasterr, string, args); | |
540 | - va_end (args); | |
541 | - return_to_top_level (RETURN_ERROR); | |
542 | - } | |
547 | + verror (string, args); | |
548 | + va_end (args); | |
543 | 549 | } |
544 | 550 | |
545 | -/* Allows the error message to be passed on a stream buffer */ | |
546 | - | |
547 | 551 | NORETURN void |
548 | 552 | error_stream (GDB_FILE *stream) |
549 | 553 | { |
550 | - error (tui_file_get_strbuf (stream)); | |
554 | + long size; | |
555 | + char *msg = gdb_file_xstrdup (stream, &size); | |
556 | + make_cleanup (free, msg); | |
557 | + error ("%s", msg); | |
551 | 558 | } |
552 | 559 | |
553 | 560 | /* Get the last error message issued by gdb */ |
@@ -555,26 +562,26 @@ error_stream (GDB_FILE *stream) | ||
555 | 562 | char * |
556 | 563 | error_last_message (void) |
557 | 564 | { |
558 | - return (tui_file_get_strbuf (gdb_lasterr)); | |
565 | + long len; | |
566 | + return gdb_file_xstrdup (gdb_lasterr, &len); | |
559 | 567 | } |
560 | - | |
568 | + | |
561 | 569 | /* This is to be called by main() at the very beginning */ |
562 | 570 | |
563 | 571 | void |
564 | 572 | error_init (void) |
565 | 573 | { |
566 | - gdb_lasterr = tui_sfileopen (132); | |
574 | + gdb_lasterr = mem_fileopen (); | |
567 | 575 | } |
568 | 576 | |
569 | 577 | /* Print a message reporting an internal error. Ask the user if they |
570 | 578 | want to continue, dump core, or just exit. */ |
571 | 579 | |
572 | 580 | NORETURN void |
573 | -internal_error (char *string, ...) | |
581 | +internal_verror (const char *fmt, va_list ap) | |
574 | 582 | { |
575 | 583 | static char msg[] = "Internal GDB error: recursive internal error.\n"; |
576 | 584 | static int dejavu = 0; |
577 | - va_list args; | |
578 | 585 | int continue_p; |
579 | 586 | int dump_core_p; |
580 | 587 |
@@ -596,9 +603,7 @@ internal_error (char *string, ...) | ||
596 | 603 | |
597 | 604 | /* Try to get the message out */ |
598 | 605 | fputs_unfiltered ("gdb-internal-error: ", gdb_stderr); |
599 | - va_start (args, string); | |
600 | - vfprintf_unfiltered (gdb_stderr, string, args); | |
601 | - va_end (args); | |
606 | + vfprintf_unfiltered (gdb_stderr, fmt, ap); | |
602 | 607 | fputs_unfiltered ("\n", gdb_stderr); |
603 | 608 | |
604 | 609 | /* Default (no case) is to quit GDB. When in batch mode this |
@@ -632,6 +637,15 @@ Create a core file containing the current state of GDB? "); | ||
632 | 637 | return_to_top_level (RETURN_ERROR); |
633 | 638 | } |
634 | 639 | |
640 | +NORETURN void | |
641 | +internal_error (char *string, ...) | |
642 | +{ | |
643 | + va_list ap; | |
644 | + va_start (ap, string); | |
645 | + internal_verror (string, ap); | |
646 | + va_end (ap); | |
647 | +} | |
648 | + | |
635 | 649 | /* The strerror() function can return NULL for errno values that are |
636 | 650 | out of range. Provide a "safe" version that always returns a |
637 | 651 | printable string. */ |
@@ -787,7 +801,7 @@ notice_quit () | ||
787 | 801 | immediate_quit = 1; |
788 | 802 | } |
789 | 803 | |
790 | -#else /* !defined(__GO32__) && !defined(_MSC_VER) */ | |
804 | +#else /* !defined(_MSC_VER) */ | |
791 | 805 | |
792 | 806 | void |
793 | 807 | notice_quit () |
@@ -795,7 +809,7 @@ notice_quit () | ||
795 | 809 | /* Done by signals */ |
796 | 810 | } |
797 | 811 | |
798 | -#endif /* !defined(__GO32__) && !defined(_MSC_VER) */ | |
812 | +#endif /* !defined(_MSC_VER) */ | |
799 | 813 | |
800 | 814 | /* Control C comes here */ |
801 | 815 | void |
@@ -1754,19 +1768,20 @@ stdio_fileopen (file) | ||
1754 | 1768 | |
1755 | 1769 | |
1756 | 1770 | /* A pure memory based ``struct gdb_file'' that can be used an output |
1757 | - collector. It's input is available through gdb_file_put(). */ | |
1771 | + buffer. The buffers accumulated contents are available via | |
1772 | + gdb_file_put(). */ | |
1758 | 1773 | |
1759 | 1774 | struct mem_file |
1760 | 1775 | { |
1761 | 1776 | int *magic; |
1762 | 1777 | char *buffer; |
1763 | 1778 | int sizeof_buffer; |
1764 | - int strlen_buffer; | |
1779 | + int length_buffer; | |
1765 | 1780 | }; |
1766 | 1781 | |
1767 | -extern gdb_file_fputs_ftype mem_file_fputs; | |
1768 | 1782 | static gdb_file_rewind_ftype mem_file_rewind; |
1769 | 1783 | static gdb_file_put_ftype mem_file_put; |
1784 | +static gdb_file_write_ftype mem_file_write; | |
1770 | 1785 | static gdb_file_delete_ftype mem_file_delete; |
1771 | 1786 | static struct gdb_file *mem_file_new PARAMS ((void)); |
1772 | 1787 | static int mem_file_magic; |
@@ -1777,12 +1792,13 @@ mem_file_new (void) | ||
1777 | 1792 | struct mem_file *stream = XMALLOC (struct mem_file); |
1778 | 1793 | struct gdb_file *file = gdb_file_new (); |
1779 | 1794 | set_gdb_file_data (file, stream, mem_file_delete); |
1780 | - set_gdb_file_fputs (file, mem_file_fputs); | |
1781 | 1795 | set_gdb_file_rewind (file, mem_file_rewind); |
1782 | 1796 | set_gdb_file_put (file, mem_file_put); |
1797 | + set_gdb_file_write (file, mem_file_write); | |
1783 | 1798 | stream->magic = &mem_file_magic; |
1784 | 1799 | stream->buffer = NULL; |
1785 | 1800 | stream->sizeof_buffer = 0; |
1801 | + stream->length_buffer = 0; | |
1786 | 1802 | return file; |
1787 | 1803 | } |
1788 | 1804 |
@@ -1809,52 +1825,49 @@ mem_file_rewind (struct gdb_file *file) | ||
1809 | 1825 | struct mem_file *stream = gdb_file_data (file); |
1810 | 1826 | if (stream->magic != &mem_file_magic) |
1811 | 1827 | internal_error ("mem_file_rewind: bad magic number"); |
1812 | - if (stream->buffer != NULL) | |
1813 | - { | |
1814 | - stream->buffer[0] = '\0'; | |
1815 | - stream->strlen_buffer = 0; | |
1816 | - } | |
1828 | + stream->length_buffer = 0; | |
1817 | 1829 | } |
1818 | 1830 | |
1819 | 1831 | static void |
1820 | -mem_file_put (struct gdb_file *file, struct gdb_file *dest) | |
1832 | +mem_file_put (struct gdb_file *file, | |
1833 | + gdb_file_put_method_ftype *write, | |
1834 | + void *dest) | |
1821 | 1835 | { |
1822 | 1836 | struct mem_file *stream = gdb_file_data (file); |
1823 | 1837 | if (stream->magic != &mem_file_magic) |
1824 | 1838 | internal_error ("mem_file_put: bad magic number"); |
1825 | - if (stream->buffer != NULL) | |
1826 | - fputs_unfiltered (stream->buffer, dest); | |
1839 | + if (stream->length_buffer > 0) | |
1840 | + write (dest, stream->buffer, stream->length_buffer); | |
1827 | 1841 | } |
1828 | 1842 | |
1829 | 1843 | void |
1830 | -mem_file_fputs (const char *linebuffer, struct gdb_file *file) | |
1844 | +mem_file_write (struct gdb_file *file, | |
1845 | + const char *buffer, | |
1846 | + long length_buffer) | |
1831 | 1847 | { |
1832 | 1848 | struct mem_file *stream = gdb_file_data (file); |
1833 | 1849 | if (stream->magic != &mem_file_magic) |
1834 | - internal_error ("mem_file_fputs: bad magic number"); | |
1850 | + internal_error ("mem_file_write: bad magic number"); | |
1835 | 1851 | if (stream->buffer == NULL) |
1836 | 1852 | { |
1837 | - stream->strlen_buffer = strlen (linebuffer); | |
1838 | - stream->sizeof_buffer = stream->strlen_buffer + 1; | |
1853 | + stream->length_buffer = length_buffer; | |
1854 | + stream->sizeof_buffer = length_buffer; | |
1839 | 1855 | stream->buffer = xmalloc (stream->sizeof_buffer); |
1840 | - strcpy (stream->buffer, linebuffer); | |
1856 | + memcpy (stream->buffer, buffer, length_buffer); | |
1841 | 1857 | } |
1842 | 1858 | else |
1843 | 1859 | { |
1844 | - int len = strlen (linebuffer); | |
1845 | - int new_strlen = stream->strlen_buffer + len; | |
1846 | - int new_sizeof = new_strlen + 1; | |
1847 | - if (new_sizeof >= stream->sizeof_buffer) | |
1860 | + int new_length = stream->length_buffer + length_buffer; | |
1861 | + if (new_length >= stream->sizeof_buffer) | |
1848 | 1862 | { |
1849 | - stream->sizeof_buffer = new_sizeof; | |
1863 | + stream->sizeof_buffer = new_length; | |
1850 | 1864 | stream->buffer = xrealloc (stream->buffer, stream->sizeof_buffer); |
1851 | 1865 | } |
1852 | - strcpy (stream->buffer + stream->strlen_buffer, linebuffer); | |
1853 | - stream->strlen_buffer = new_strlen; | |
1866 | + memcpy (stream->buffer + stream->length_buffer, buffer, length_buffer); | |
1867 | + stream->length_buffer = new_length; | |
1854 | 1868 | } |
1855 | 1869 | } |
1856 | 1870 | |
1857 | - | |
1858 | 1871 | /* A ``struct gdb_file'' that is compatible with all the legacy |
1859 | 1872 | code. */ |
1860 | 1873 |
@@ -1972,17 +1985,15 @@ tui_file_rewind (file) | ||
1972 | 1985 | } |
1973 | 1986 | |
1974 | 1987 | static void |
1975 | -tui_file_put (file, dest) | |
1976 | - struct gdb_file *file; | |
1977 | - struct gdb_file *dest; | |
1988 | +tui_file_put (struct gdb_file *file, | |
1989 | + gdb_file_put_method_ftype *write, | |
1990 | + void *dest) | |
1978 | 1991 | { |
1979 | 1992 | struct tui_stream *stream = gdb_file_data (file); |
1980 | 1993 | if (stream->ts_magic != &tui_file_magic) |
1981 | 1994 | internal_error ("tui_file_put: bad magic number"); |
1982 | 1995 | if (stream->ts_streamtype == astring) |
1983 | - { | |
1984 | - fputs_unfiltered (stream->ts_strbuf, dest); | |
1985 | - } | |
1996 | + write (dest, stream->ts_strbuf, strlen (stream->ts_strbuf)); | |
1986 | 1997 | } |
1987 | 1998 | |
1988 | 1999 | /* All TUI I/O sent to the *_filtered and *_unfiltered functions |
@@ -2149,6 +2160,7 @@ static gdb_file_put_ftype null_file_put; | ||
2149 | 2160 | |
2150 | 2161 | struct gdb_file |
2151 | 2162 | { |
2163 | + int *magic; | |
2152 | 2164 | gdb_file_flush_ftype *to_flush; |
2153 | 2165 | gdb_file_write_ftype *to_write; |
2154 | 2166 | gdb_file_fputs_ftype *to_fputs; |
@@ -2158,11 +2170,13 @@ struct gdb_file | ||
2158 | 2170 | gdb_file_put_ftype *to_put; |
2159 | 2171 | void *to_data; |
2160 | 2172 | }; |
2173 | +int gdb_file_magic; | |
2161 | 2174 | |
2162 | 2175 | struct gdb_file * |
2163 | 2176 | gdb_file_new () |
2164 | 2177 | { |
2165 | 2178 | struct gdb_file *file = xmalloc (sizeof (struct gdb_file)); |
2179 | + file->magic = &gdb_file_magic; | |
2166 | 2180 | set_gdb_file_data (file, NULL, null_file_delete); |
2167 | 2181 | set_gdb_file_flush (file, null_file_flush); |
2168 | 2182 | set_gdb_file_write (file, null_file_write); |
@@ -2196,9 +2210,9 @@ null_file_rewind (file) | ||
2196 | 2210 | } |
2197 | 2211 | |
2198 | 2212 | static void |
2199 | -null_file_put (file, src) | |
2200 | - struct gdb_file *file; | |
2201 | - struct gdb_file *src; | |
2213 | +null_file_put (struct gdb_file *file, | |
2214 | + gdb_file_put_method_ftype *write, | |
2215 | + void *dest) | |
2202 | 2216 | { |
2203 | 2217 | return; |
2204 | 2218 | } |
@@ -2265,6 +2279,8 @@ void * | ||
2265 | 2279 | gdb_file_data (file) |
2266 | 2280 | struct gdb_file *file; |
2267 | 2281 | { |
2282 | + if (file->magic != &gdb_file_magic) | |
2283 | + internal_error ("gdb_file_data: bad magic number"); | |
2268 | 2284 | return file->to_data; |
2269 | 2285 | } |
2270 | 2286 |
@@ -2290,11 +2306,11 @@ gdb_file_rewind (file) | ||
2290 | 2306 | } |
2291 | 2307 | |
2292 | 2308 | void |
2293 | -gdb_file_put (file, dest) | |
2294 | - struct gdb_file *file; | |
2295 | - struct gdb_file *dest; | |
2309 | +gdb_file_put (struct gdb_file *file, | |
2310 | + gdb_file_put_method_ftype *write, | |
2311 | + void *dest) | |
2296 | 2312 | { |
2297 | - file->to_put (file, dest); | |
2313 | + file->to_put (file, write, dest); | |
2298 | 2314 | } |
2299 | 2315 | |
2300 | 2316 | void |
@@ -2370,6 +2386,43 @@ set_gdb_file_data (file, data, delete) | ||
2370 | 2386 | file->to_delete = delete; |
2371 | 2387 | } |
2372 | 2388 | |
2389 | +/* gdb_file utility function for converting a ``struct gdb_file'' into | |
2390 | + a memory buffer''. */ | |
2391 | + | |
2392 | +struct accumulated_gdb_file | |
2393 | +{ | |
2394 | + char *buffer; | |
2395 | + long length; | |
2396 | +}; | |
2397 | + | |
2398 | +static void | |
2399 | +do_gdb_file_xstrdup (void *context, const char *buffer, long length) | |
2400 | +{ | |
2401 | + struct accumulated_gdb_file *acc = context; | |
2402 | + if (acc->buffer == NULL) | |
2403 | + acc->buffer = xmalloc (length + 1); | |
2404 | + else | |
2405 | + acc->buffer = xrealloc (acc->buffer, acc->length + length + 1); | |
2406 | + memcpy (acc->buffer + acc->length, buffer, length); | |
2407 | + acc->length += length; | |
2408 | + acc->buffer[acc->length] = '\0'; | |
2409 | +} | |
2410 | + | |
2411 | +char * | |
2412 | +gdb_file_xstrdup (struct gdb_file *file, | |
2413 | + long *length) | |
2414 | +{ | |
2415 | + struct accumulated_gdb_file acc; | |
2416 | + acc.buffer = NULL; | |
2417 | + acc.length = 0; | |
2418 | + gdb_file_put (file, do_gdb_file_xstrdup, &acc); | |
2419 | + if (acc.buffer == NULL) | |
2420 | + acc.buffer = xstrdup (""); | |
2421 | + *length = acc.length; | |
2422 | + return acc.buffer; | |
2423 | +} | |
2424 | + | |
2425 | + | |
2373 | 2426 | /* Like fputs but if FILTER is true, pause after every screenful. |
2374 | 2427 | |
2375 | 2428 | Regardless of FILTER can wrap at points other than the final |
@@ -1,7 +1,88 @@ | ||
1 | +Fri Oct 29 18:34:28 1999 Andrew Cagney <cagney@b1.cygnus.com> | |
2 | + | |
3 | + * simops.c (move_to_cr): Don't allow user to set PSW.DM in either | |
4 | + DPSW and BPSW. | |
5 | + | |
6 | +Thu Oct 28 01:26:18 1999 Andrew Cagney <cagney@b1.cygnus.com> | |
7 | + | |
8 | + * simops.c (OP_5F20): Use SET_HW_PSW when updating PSW. | |
9 | + (PSW_HW_MASK): Declare. | |
10 | + | |
11 | + * d10v_sim.h (move_to_cr): Add ``psw_hw_p'' parameter. | |
12 | + (SET_CREG, SET_PSW_BIT): Update. | |
13 | + (SET_HW_CREG, SET_HW_PSW): Define. | |
14 | + | |
15 | +Sun Oct 24 21:38:04 1999 Andrew Cagney <cagney@b1.cygnus.com> | |
16 | + | |
17 | + * interp.c (sim_d10v_translate_dmap_addr): Fix extraction of IOSP | |
18 | + for DMAP3. | |
19 | + | |
20 | +Sun Oct 24 16:04:16 1999 Andrew Cagney <cagney@b1.cygnus.com> | |
21 | + | |
22 | + * interp.c (sim_d10v_translate_addr): New function. | |
23 | + (xfer_mem): Rewrite. Use sim_d10v_translate_addr. | |
24 | + (map_memory): Make INLINE. | |
25 | + | |
26 | +Sun Oct 24 13:45:19 1999 Andrew Cagney <cagney@b1.cygnus.com> | |
27 | + | |
28 | + * interp.c (sim_d10v_translate_dmap_addr): New function. | |
29 | + (dmem_addr): Rewrite. Use sim_d10v_translate_dmap_addr. Change | |
30 | + offset parameter to type uint16. | |
31 | + * d10v_sim.h (dmem_addr): Update declaration. | |
32 | + | |
33 | +Sun Oct 24 13:07:31 1999 Andrew Cagney <cagney@b1.cygnus.com> | |
34 | + | |
35 | + * interp.c (imap_register, set_imap_register, dmap_register, | |
36 | + set_imap_register): Use map_memory. | |
37 | + (DMAP): Update. | |
38 | + (sim_create_inferior): Initialize all DMAP registers. NOTE that | |
39 | + DMAP2, in internal memory mode, is set to 0x0000 and NOT | |
40 | + 0x2000. This is consistent with the older d10v boards. | |
41 | + | |
42 | +Sun Oct 24 11:22:12 1999 Andrew Cagney <cagney@b1.cygnus.com> | |
43 | + | |
44 | + * interp.c (sim_d10v_translate_imap_addr): New function. | |
45 | + (imem_addr): Rewrite. Use sim_d10v_translate_imap_addr. | |
46 | + (last_from, last_to): Declare. | |
47 | + | |
48 | +Sun Oct 24 01:21:56 1999 Andrew Cagney <cagney@b1.cygnus.com> | |
49 | + | |
50 | + * d10v_sim.h (struct d10v_memory): Define. Support very long | |
51 | + memories. | |
52 | + (struct _state): Replace imem, dmem and umem by mem. | |
53 | + (IMAP_BLOCK_SIZE, DMAP_BLOCK_SIZE, SEGMENT_SIZE, IMEM_SEGMENTS, | |
54 | + DMEM_SEGMENTS, UMEM_SEGMENTS): Define. | |
55 | + | |
56 | + * interp.c (map_memory): New function. | |
57 | + (sim_size, xfer_memory, imem_addr, dmem_addr): Update. | |
58 | + (UMEM_SEGMENTS): Moveed to "d10v_sim.h". | |
59 | + (IMEM_SIZEDMEM_SIZE): Delete. | |
60 | + | |
61 | +Sat Oct 23 20:06:58 1999 Andrew Cagney <cagney@b1.cygnus.com> | |
62 | + | |
63 | + * interp.c: Include "sim-d10v.h". | |
64 | + (imap_register, set_imap_register, dmap_register, | |
65 | + set_dmap_register, spi_register, spu_register, set_spi_register, | |
66 | + set_spu_register): New functions. | |
67 | + (sim_create_inferior): Update. | |
68 | + (sim_fetch_register, sim_store_register): Rewrite. Use enums | |
69 | + defined in sim-d10v.h. | |
70 | + | |
71 | + * d10v_sim.h (DEBUG_MEMORY): Define. | |
72 | + (IMAP0, IMAP1, DMAP, SET_IMAP0, SET_IMAP1, SET_DMAP): Delete. | |
73 | + | |
74 | +Sat Oct 23 18:41:18 1999 Andrew Cagney <cagney@b1.cygnus.com> | |
75 | + | |
76 | + * interp.c (sim_open): Allow a debug value to be passed to the -t | |
77 | + option. | |
78 | + (lookup_hash): Don't exit on an illegal instruction. | |
79 | + (do_long, do_2_short, do_parallel): Check for failed instruction | |
80 | + lookup. | |
81 | + | |
1 | 82 | Mon Oct 18 18:03:24 MDT 1999 Diego Novillo <dnovillo@cygnus.com> |
2 | 83 | |
3 | 84 | * simops.c (OP_3220): Fix trace output for illegal accumulator |
4 | - message. | |
85 | + message. | |
5 | 86 | |
6 | 87 | 1999-09-14 Nick Clifton <nickc@cygnus.com> |
7 | 88 |
@@ -13,6 +13,7 @@ | ||
13 | 13 | #define DEBUG_MEMSIZE 0x00000008 |
14 | 14 | #define DEBUG_INSTRUCTION 0x00000010 |
15 | 15 | #define DEBUG_TRAP 0x00000020 |
16 | +#define DEBUG_MEMORY 0x00000040 | |
16 | 17 | |
17 | 18 | #ifndef DEBUG |
18 | 19 | #define DEBUG (DEBUG_TRACE | DEBUG_VALUES | DEBUG_LINE_NUMBER) |
@@ -197,6 +198,37 @@ enum { | ||
197 | 198 | } \ |
198 | 199 | while (0) |
199 | 200 | |
201 | +/* d10v memory: There are three separate d10v memory regions IMEM, | |
202 | + UMEM and DMEM. The IMEM and DMEM are further broken down into | |
203 | + blocks (very like VM pages). */ | |
204 | + | |
205 | +enum | |
206 | +{ | |
207 | + IMAP_BLOCK_SIZE = 0x20000, | |
208 | + DMAP_BLOCK_SIZE = 0x4000, | |
209 | +}; | |
210 | + | |
211 | +/* Implement the three memory regions using sparse arrays. Allocate | |
212 | + memory using ``segments''. A segment must be at least as large as | |
213 | + a BLOCK - ensures that an access that doesn't cross a block | |
214 | + boundary can't cross a segment boundary */ | |
215 | + | |
216 | +enum | |
217 | +{ | |
218 | + SEGMENT_SIZE = 0x20000, /* 128KB - MAX(IMAP_BLOCK_SIZE,DMAP_BLOCK_SIZE) */ | |
219 | + IMEM_SEGMENTS = 8, /* 1MB */ | |
220 | + DMEM_SEGMENTS = 8, /* 1MB */ | |
221 | + UMEM_SEGMENTS = 128 /* 16MB */ | |
222 | +}; | |
223 | + | |
224 | +struct d10v_memory | |
225 | +{ | |
226 | + uint8 *insn[IMEM_SEGMENTS]; | |
227 | + uint8 *data[DMEM_SEGMENTS]; | |
228 | + uint8 *unif[UMEM_SEGMENTS]; | |
229 | + uint8 fault[16]; | |
230 | +}; | |
231 | + | |
200 | 232 | struct _state |
201 | 233 | { |
202 | 234 | reg_t regs[16]; /* general-purpose registers */ |
@@ -209,7 +241,8 @@ struct _state | ||
209 | 241 | |
210 | 242 | reg_t cregs[16]; /* control registers */ |
211 | 243 | #define CREG(N) (State.cregs[(N)] + 0) |
212 | -#define SET_CREG(N,VAL) move_to_cr ((N), 0, (VAL)) | |
244 | +#define SET_CREG(N,VAL) move_to_cr ((N), 0, (VAL), 0) | |
245 | +#define SET_HW_CREG(N,VAL) move_to_cr ((N), 0, (VAL), 1) | |
213 | 246 | |
214 | 247 | reg_t sp[2]; /* holding area for SPI(0)/SPU(1) */ |
215 | 248 | #define HELD_SP(N) (State.sp[(N)] + 0) |
@@ -232,10 +265,11 @@ struct _state | ||
232 | 265 | int exception; |
233 | 266 | int pc_changed; |
234 | 267 | |
235 | - /* NOTE: everything below this line is not reset by sim_create_inferior() */ | |
236 | - uint8 *imem; | |
237 | - uint8 *dmem; | |
238 | - uint8 *umem[128]; | |
268 | + /* NOTE: everything below this line is not reset by | |
269 | + sim_create_inferior() */ | |
270 | + | |
271 | + struct d10v_memory mem; | |
272 | + | |
239 | 273 | enum _ins_type ins_type; |
240 | 274 | |
241 | 275 | } State; |
@@ -283,7 +317,8 @@ enum | ||
283 | 317 | |
284 | 318 | #define PSW CREG (PSW_CR) |
285 | 319 | #define SET_PSW(VAL) SET_CREG (PSW_CR, (VAL)) |
286 | -#define SET_PSW_BIT(MASK,VAL) move_to_cr (PSW_CR, ~(MASK), (VAL) ? (MASK) : 0) | |
320 | +#define SET_HW_PSW(VAL) SET_HW_CREG (PSW_CR, (VAL)) | |
321 | +#define SET_PSW_BIT(MASK,VAL) move_to_cr (PSW_CR, ~(MASK), (VAL) ? (MASK) : 0, 1) | |
287 | 322 | |
288 | 323 | #define PSW_SM ((PSW & PSW_SM_BIT) != 0) |
289 | 324 | #define SET_PSW_SM(VAL) SET_PSW_BIT (PSW_SM_BIT, (VAL)) |
@@ -404,7 +439,7 @@ do \ | ||
404 | 439 | } \ |
405 | 440 | while (0) |
406 | 441 | |
407 | -extern uint8 *dmem_addr PARAMS ((uint32)); | |
442 | +extern uint8 *dmem_addr (uint16 offset); | |
408 | 443 | extern uint8 *imem_addr PARAMS ((uint32)); |
409 | 444 | extern bfd_vma decode_pc PARAMS ((void)); |
410 | 445 |
@@ -434,13 +469,6 @@ extern void write_longlong PARAMS ((uint8 *addr, int64 data)); | ||
434 | 469 | #define READ_64(x) get_longlong(x) |
435 | 470 | #define WRITE_64(addr,data) write_longlong(addr,data) |
436 | 471 | |
437 | -#define IMAP0 RW(0xff00) | |
438 | -#define IMAP1 RW(0xff02) | |
439 | -#define DMAP RW(0xff04) | |
440 | -#define SET_IMAP0(x) SW(0xff00,x) | |
441 | -#define SET_IMAP1(x) SW(0xff02,x) | |
442 | -#define SET_DMAP(x) SW(0xff04,x) | |
443 | - | |
444 | 472 | #define JMP(x) do { SET_PC (x); State.pc_changed = 1; } while (0) |
445 | 473 | |
446 | 474 | #define RIE_VECTOR_START 0xffc2 |
@@ -449,4 +477,9 @@ extern void write_longlong PARAMS ((uint8 *addr, int64 data)); | ||
449 | 477 | #define DBT_VECTOR_START 0xffd4 |
450 | 478 | #define SDBT_VECTOR_START 0xffd5 |
451 | 479 | |
452 | -extern reg_t move_to_cr PARAMS ((int cr, reg_t mask, reg_t val)); | |
480 | +/* Scedule a store of VAL into cr[CR]. MASK indicates the bits in | |
481 | + cr[CR] that should not be modified (i.e. cr[CR] = (cr[CR] & MASK) | | |
482 | + (VAL & ~MASK)). In addition, unless PSW_HW_P, a VAL intended for | |
483 | + PSW is masked for zero bits. */ | |
484 | + | |
485 | +extern reg_t move_to_cr (int cr, reg_t mask, reg_t val, int psw_hw_p); |
@@ -5,11 +5,7 @@ | ||
5 | 5 | #include "remote-sim.h" |
6 | 6 | |
7 | 7 | #include "d10v_sim.h" |
8 | - | |
9 | -#define IMEM_SIZE 18 /* D10V instruction memory size is 18 bits */ | |
10 | -#define DMEM_SIZE 16 /* Data memory is 64K (but only 32K internal RAM) */ | |
11 | -#define UMEM_SIZE 17 /* Each unified memory segment is 17 bits */ | |
12 | -#define UMEM_SEGMENTS 128 /* Number of segments in unified memory region */ | |
8 | +#include "sim-d10v.h" | |
13 | 9 | |
14 | 10 | enum _leftright { LEFT_FIRST, RIGHT_FIRST }; |
15 | 11 |
@@ -43,6 +39,7 @@ static void do_parallel PARAMS ((uint16 ins1, uint16 ins2)); | ||
43 | 39 | static char *add_commas PARAMS ((char *buf, int sizeof_buf, unsigned long value)); |
44 | 40 | extern void sim_set_profile PARAMS ((int n)); |
45 | 41 | extern void sim_set_profile_size PARAMS ((int n)); |
42 | +static INLINE uint8 *map_memory (unsigned phys_addr); | |
46 | 43 | |
47 | 44 | #ifdef NEED_UI_LOOP_HOOK |
48 | 45 | /* How often to run the ui_loop update, when in use */ |
@@ -102,8 +99,10 @@ lookup_hash (ins, size) | ||
102 | 99 | { |
103 | 100 | if (h->next == NULL) |
104 | 101 | { |
105 | - (*d10v_callback->printf_filtered) (d10v_callback, "ERROR looking up hash for %x at PC %x\n",ins, PC); | |
106 | - exit (1); | |
102 | + (*d10v_callback->printf_filtered) | |
103 | + (d10v_callback, "ERROR: Illegal instruction %x at PC %x\n", ins, PC); | |
104 | + State.exception = SIGILL; | |
105 | + return NULL; | |
107 | 106 | } |
108 | 107 | h = h->next; |
109 | 108 | } |
@@ -158,6 +157,8 @@ do_long (ins) | ||
158 | 157 | (*d10v_callback->printf_filtered) (d10v_callback, "do_long 0x%x\n", ins); |
159 | 158 | #endif |
160 | 159 | h = lookup_hash (ins, 1); |
160 | + if (h == NULL) | |
161 | + return; | |
161 | 162 | get_operands (h->ops, ins); |
162 | 163 | State.ins_type = INS_LONG; |
163 | 164 | ins_type_counters[ (int)State.ins_type ]++; |
@@ -193,6 +194,8 @@ do_2_short (ins1, ins2, leftright) | ||
193 | 194 | |
194 | 195 | /* Issue the first instruction */ |
195 | 196 | h = lookup_hash (ins1, 0); |
197 | + if (h == NULL) | |
198 | + return; | |
196 | 199 | get_operands (h->ops, ins1); |
197 | 200 | State.ins_type = first; |
198 | 201 | ins_type_counters[ (int)State.ins_type ]++; |
@@ -204,6 +207,8 @@ do_2_short (ins1, ins2, leftright) | ||
204 | 207 | /* finish any existing instructions */ |
205 | 208 | SLOT_FLUSH (); |
206 | 209 | h = lookup_hash (ins2, 0); |
210 | + if (h == NULL) | |
211 | + return; | |
207 | 212 | get_operands (h->ops, ins2); |
208 | 213 | State.ins_type = second; |
209 | 214 | ins_type_counters[ (int)State.ins_type ]++; |
@@ -225,7 +230,11 @@ do_parallel (ins1, ins2) | ||
225 | 230 | #endif |
226 | 231 | ins_type_counters[ (int)INS_PARALLEL ]++; |
227 | 232 | h1 = lookup_hash (ins1, 0); |
233 | + if (h1 == NULL) | |
234 | + return; | |
228 | 235 | h2 = lookup_hash (ins2, 0); |
236 | + if (h2 == NULL) | |
237 | + return; | |
229 | 238 | |
230 | 239 | if (h1->ops->exec_type == PARONLY) |
231 | 240 | { |
@@ -306,252 +315,446 @@ sim_size (power) | ||
306 | 315 | |
307 | 316 | { |
308 | 317 | int i; |
309 | - | |
310 | - if (State.imem) | |
318 | + for (i = 0; i < IMEM_SEGMENTS; i++) | |
311 | 319 | { |
312 | - for (i=0;i<UMEM_SEGMENTS;i++) | |
313 | - { | |
314 | - if (State.umem[i]) | |
315 | - { | |
316 | - free (State.umem[i]); | |
317 | - State.umem[i] = NULL; | |
318 | - } | |
319 | - } | |
320 | - free (State.imem); | |
321 | - free (State.dmem); | |
320 | + if (State.mem.insn[i]) | |
321 | + free (State.mem.insn[i]); | |
322 | 322 | } |
323 | - | |
324 | - State.imem = (uint8 *)calloc(1,1<<IMEM_SIZE); | |
325 | - State.dmem = (uint8 *)calloc(1,1<<DMEM_SIZE); | |
326 | - for (i=1;i<(UMEM_SEGMENTS-1);i++) | |
327 | - State.umem[i] = NULL; | |
328 | - State.umem[0] = (uint8 *)calloc(1,1<<UMEM_SIZE); | |
329 | - State.umem[1] = (uint8 *)calloc(1,1<<UMEM_SIZE); | |
330 | - State.umem[2] = (uint8 *)calloc(1,1<<UMEM_SIZE); | |
331 | - State.umem[UMEM_SEGMENTS-1] = (uint8 *)calloc(1,1<<UMEM_SIZE); | |
332 | - if (!State.imem || !State.dmem || !State.umem[0] || !State.umem[1] || !State.umem[2] || !State.umem[UMEM_SEGMENTS-1] ) | |
323 | + for (i = 0; i < DMEM_SEGMENTS; i++) | |
333 | 324 | { |
334 | - (*d10v_callback->printf_filtered) (d10v_callback, "Memory allocation failed.\n"); | |
335 | - exit(1); | |
325 | + if (State.mem.data[i]) | |
326 | + free (State.mem.data[i]); | |
336 | 327 | } |
337 | - | |
328 | + for (i = 0; i < UMEM_SEGMENTS; i++) | |
329 | + { | |
330 | + if (State.mem.unif[i]) | |
331 | + free (State.mem.unif[i]); | |
332 | + } | |
333 | + /* Always allocate dmem segment 0. This contains the IMAP and DMAP | |
334 | + registers. */ | |
335 | + State.mem.data[0] = calloc (1, SEGMENT_SIZE); | |
336 | +} | |
337 | + | |
338 | +/* For tracing - leave info on last access around. */ | |
339 | +static char *last_segname = "invalid"; | |
340 | +static char *last_from = "invalid"; | |
341 | +static char *last_to = "invalid"; | |
342 | + | |
343 | +enum | |
344 | + { | |
345 | + IMAP0_OFFSET = 0xff00, | |
346 | + DMAP0_OFFSET = 0xff08, | |
347 | + DMAP2_SHADDOW = 0xff04, | |
348 | + DMAP2_OFFSET = 0xff0c | |
349 | + }; | |
350 | + | |
351 | +static void | |
352 | +set_dmap_register (int reg_nr, unsigned long value) | |
353 | +{ | |
354 | + uint8 *raw = map_memory (SIM_D10V_MEMORY_DATA | |
355 | + + DMAP0_OFFSET + 2 * reg_nr); | |
356 | + WRITE_16 (raw, value); | |
338 | 357 | #ifdef DEBUG |
339 | - if ((d10v_debug & DEBUG_MEMSIZE) != 0) | |
358 | + if ((d10v_debug & DEBUG_MEMORY)) | |
340 | 359 | { |
341 | - char buffer[20]; | |
342 | - (*d10v_callback->printf_filtered) (d10v_callback, | |
343 | - "Allocated %s bytes instruction memory and\n", | |
344 | - add_commas (buffer, sizeof (buffer), (1UL<<IMEM_SIZE))); | |
360 | + (*d10v_callback->printf_filtered) | |
361 | + (d10v_callback, "mem: dmap%d=0x%04lx\n", reg_nr, value); | |
362 | + } | |
363 | +#endif | |
364 | +} | |
345 | 365 | |
346 | - (*d10v_callback->printf_filtered) (d10v_callback, " %s bytes data memory.\n", | |
347 | - add_commas (buffer, sizeof (buffer), (1UL<<IMEM_SIZE))); | |
366 | +static unsigned long | |
367 | +dmap_register (int reg_nr) | |
368 | +{ | |
369 | + uint8 *raw = map_memory (SIM_D10V_MEMORY_DATA | |
370 | + + DMAP0_OFFSET + 2 * reg_nr); | |
371 | + return READ_16 (raw); | |
372 | +} | |
373 | + | |
374 | +static void | |
375 | +set_imap_register (int reg_nr, unsigned long value) | |
376 | +{ | |
377 | + uint8 *raw = map_memory (SIM_D10V_MEMORY_DATA | |
378 | + + IMAP0_OFFSET + 2 * reg_nr); | |
379 | + WRITE_16 (raw, value); | |
380 | +#ifdef DEBUG | |
381 | + if ((d10v_debug & DEBUG_MEMORY)) | |
382 | + { | |
383 | + (*d10v_callback->printf_filtered) | |
384 | + (d10v_callback, "mem: imap%d=0x%04lx\n", reg_nr, value); | |
348 | 385 | } |
349 | 386 | #endif |
350 | 387 | } |
351 | 388 | |
352 | -/* Transfer data to/from simulated memory. Since a bug in either the | |
353 | - simulated program or in gdb or the simulator itself may cause a | |
354 | - bogus address to be passed in, we need to do some sanity checking | |
355 | - on addresses to make sure they are within bounds. When an address | |
356 | - fails the bounds check, treat it as a zero length read/write rather | |
357 | - than aborting the entire run. */ | |
389 | +static unsigned long | |
390 | +imap_register (int reg_nr) | |
391 | +{ | |
392 | + uint8 *raw = map_memory (SIM_D10V_MEMORY_DATA | |
393 | + + IMAP0_OFFSET + 2 * reg_nr); | |
394 | + return READ_16 (raw); | |
395 | +} | |
358 | 396 | |
359 | -static int | |
360 | -xfer_mem (SIM_ADDR addr, | |
361 | - unsigned char *buffer, | |
362 | - int size, | |
363 | - int write_p) | |
397 | +enum | |
398 | + { | |
399 | + HELD_SPI_IDX = 0, | |
400 | + HELD_SPU_IDX = 1 | |
401 | + }; | |
402 | + | |
403 | +static unsigned long | |
404 | +spu_register (void) | |
364 | 405 | { |
365 | - unsigned char *memory; | |
366 | - int segment = ((addr >> 24) & 0xff); | |
367 | - addr = (addr & 0x00ffffff); | |
406 | + if (PSW_SM) | |
407 | + return GPR (SP_IDX); | |
408 | + else | |
409 | + return HELD_SP (HELD_SPU_IDX); | |
410 | +} | |
368 | 411 | |
369 | -#ifdef DEBUG | |
370 | - if ((d10v_debug & DEBUG_INSTRUCTION) != 0) | |
412 | +static unsigned long | |
413 | +spi_register (void) | |
414 | +{ | |
415 | + if (!PSW_SM) | |
416 | + return GPR (SP_IDX); | |
417 | + else | |
418 | + return HELD_SP (HELD_SPI_IDX); | |
419 | +} | |
420 | + | |
421 | +static void | |
422 | +set_spi_register (unsigned long value) | |
423 | +{ | |
424 | + if (!PSW_SM) | |
425 | + SET_GPR (SP_IDX, value); | |
426 | + SET_HELD_SP (HELD_SPI_IDX, value); | |
427 | +} | |
428 | + | |
429 | +static void | |
430 | +set_spu_register (unsigned long value) | |
431 | +{ | |
432 | + if (PSW_SM) | |
433 | + SET_GPR (SP_IDX, value); | |
434 | + SET_HELD_SP (HELD_SPU_IDX, value); | |
435 | +} | |
436 | + | |
437 | +/* Given a virtual address in the DMAP address space, translate it | |
438 | + into a physical address. */ | |
439 | + | |
440 | +unsigned long | |
441 | +sim_d10v_translate_dmap_addr (unsigned long offset, | |
442 | + int nr_bytes, | |
443 | + unsigned long *phys, | |
444 | + unsigned long (*dmap_register) (int reg_nr)) | |
445 | +{ | |
446 | + short map; | |
447 | + int regno; | |
448 | + last_from = "logical-data"; | |
449 | + if (offset >= DMAP_BLOCK_SIZE * SIM_D10V_NR_DMAP_REGS) | |
371 | 450 | { |
372 | - if (write_p) | |
373 | - { | |
374 | - (*d10v_callback->printf_filtered) (d10v_callback, "sim_write %d bytes to 0x%02x:%06x\n", size, segment, addr); | |
375 | - } | |
376 | - else | |
451 | + /* Logical address out side of data segments, not supported */ | |
452 | + return 0; | |
453 | + } | |
454 | + regno = (offset / DMAP_BLOCK_SIZE); | |
455 | + offset = (offset % DMAP_BLOCK_SIZE); | |
456 | + if ((offset % DMAP_BLOCK_SIZE) + nr_bytes > DMAP_BLOCK_SIZE) | |
457 | + { | |
458 | + /* Don't cross a BLOCK boundary */ | |
459 | + nr_bytes = DMAP_BLOCK_SIZE - (offset % DMAP_BLOCK_SIZE); | |
460 | + } | |
461 | + map = dmap_register (regno); | |
462 | + if (regno == 3) | |
463 | + { | |
464 | + /* Always maps to data memory */ | |
465 | + int iospi = (offset / 0x1000) % 4; | |
466 | + int iosp = (map >> (4 * (3 - iospi))) % 0x10; | |
467 | + last_to = "io-space"; | |
468 | + *phys = (SIM_D10V_MEMORY_DATA + (iosp * 0x10000) + 0xc000 + offset); | |
469 | + } | |
470 | + else | |
471 | + { | |
472 | + int sp = ((map & 0x3000) >> 12); | |
473 | + int segno = (map & 0x3ff); | |
474 | + switch (sp) | |
377 | 475 | { |
378 | - (*d10v_callback->printf_filtered) (d10v_callback, "sim_read %d bytes from 0x%2x:%6x\n", size, segment, addr); | |
476 | + case 0: /* 00: Unified memory */ | |
477 | + *phys = SIM_D10V_MEMORY_UNIFIED + (segno * DMAP_BLOCK_SIZE) + offset; | |
478 | + last_to = "unified"; | |
479 | + break; | |
480 | + case 1: /* 01: Instruction Memory */ | |
481 | + *phys = SIM_D10V_MEMORY_INSN + (segno * DMAP_BLOCK_SIZE) + offset; | |
482 | + last_to = "chip-insn"; | |
483 | + break; | |
484 | + case 2: /* 10: Internal data memory */ | |
485 | + *phys = SIM_D10V_MEMORY_DATA + (segno << 16) + (regno * DMAP_BLOCK_SIZE) + offset; | |
486 | + last_to = "chip-data"; | |
487 | + break; | |
488 | + case 3: /* 11: Reserved */ | |
489 | + return 0; | |
379 | 490 | } |
380 | 491 | } |
381 | -#endif | |
492 | + return nr_bytes; | |
493 | +} | |
382 | 494 | |
383 | - /* To access data, we use the following mappings: | |
495 | +/* Given a virtual address in the IMAP address space, translate it | |
496 | + into a physical address. */ | |
384 | 497 | |
385 | - 0x00xxxxxx: Physical unified memory segment (Unified memory) | |
386 | - 0x01xxxxxx: Physical instruction memory segment (On-chip insn memory) | |
387 | - 0x02xxxxxx: Physical data memory segment (On-chip data memory) | |
388 | - 0x10xxxxxx: Logical data address segment (DMAP translated memory) | |
389 | - 0x11xxxxxx: Logical instruction address segment (IMAP translated memory) | |
498 | +unsigned long | |
499 | +sim_d10v_translate_imap_addr (unsigned long offset, | |
500 | + int nr_bytes, | |
501 | + unsigned long *phys, | |
502 | + unsigned long (*imap_register) (int reg_nr)) | |
503 | +{ | |
504 | + short map; | |
505 | + int regno; | |
506 | + int sp; | |
507 | + int segno; | |
508 | + last_from = "logical-insn"; | |
509 | + if (offset >= (IMAP_BLOCK_SIZE * SIM_D10V_NR_IMAP_REGS)) | |
510 | + { | |
511 | + /* Logical address outside of IMAP segments, not supported */ | |
512 | + return 0; | |
513 | + } | |
514 | + regno = (offset / IMAP_BLOCK_SIZE); | |
515 | + offset = (offset % IMAP_BLOCK_SIZE); | |
516 | + if (offset + nr_bytes > IMAP_BLOCK_SIZE) | |
517 | + { | |
518 | + /* Don't cross a BLOCK boundary */ | |
519 | + nr_bytes = IMAP_BLOCK_SIZE - offset; | |
520 | + } | |
521 | + map = imap_register (regno); | |
522 | + sp = (map & 0x3000) >> 12; | |
523 | + segno = (map & 0x007f); | |
524 | + switch (sp) | |
525 | + { | |
526 | + case 0: /* 00: unified memory */ | |
527 | + *phys = SIM_D10V_MEMORY_UNIFIED + (segno << 17) + offset; | |
528 | + last_to = "unified"; | |
529 | + break; | |
530 | + case 1: /* 01: instruction memory */ | |
531 | + *phys = SIM_D10V_MEMORY_INSN + (IMAP_BLOCK_SIZE * regno) + offset; | |
532 | + last_to = "chip-insn"; | |
533 | + break; | |
534 | + case 2: /*10*/ | |
535 | + /* Reserved. */ | |
536 | + return 0; | |
537 | + case 3: /* 11: for testing - instruction memory */ | |
538 | + offset = (offset % 0x800); | |
539 | + *phys = SIM_D10V_MEMORY_INSN + offset; | |
540 | + if (offset + nr_bytes > 0x800) | |
541 | + /* don't cross VM boundary */ | |
542 | + nr_bytes = 0x800 - offset; | |
543 | + last_to = "test-insn"; | |
544 | + break; | |
545 | + } | |
546 | + return nr_bytes; | |
547 | +} | |
390 | 548 | |
391 | - Alternatively, the "old segment mapping" is still available by setting | |
392 | - old_segment_mapping to 1. It looks like this: | |
549 | +unsigned long | |
550 | +sim_d10v_translate_addr (unsigned long memaddr, | |
551 | + int nr_bytes, | |
552 | + unsigned long *targ_addr, | |
553 | + unsigned long (*dmap_register) (int reg_nr), | |
554 | + unsigned long (*imap_register) (int reg_nr)) | |
555 | +{ | |
556 | + unsigned long phys; | |
557 | + unsigned long seg; | |
558 | + unsigned long off; | |
393 | 559 | |
394 | - 0x00xxxxxx: Logical data address segment (DMAP translated memory) | |
395 | - 0x01xxxxxx: Logical instruction address segment (IMAP translated memory) | |
396 | - 0x10xxxxxx: Physical data memory segment (On-chip data memory) | |
397 | - 0x11xxxxxx: Physical instruction memory segment (On-chip insn memory) | |
398 | - 0x12xxxxxx: Physical unified memory segment (Unified memory) | |
560 | + last_from = "unknown"; | |
561 | + last_to = "unknown"; | |
399 | 562 | |
400 | - */ | |
563 | + seg = (memaddr >> 24); | |
564 | + off = (memaddr & 0xffffffL); | |
401 | 565 | |
402 | 566 | /* However, if we've asked to use the previous generation of segment |
403 | 567 | mapping, rearrange the segments as follows. */ |
404 | 568 | |
405 | 569 | if (old_segment_mapping) |
406 | 570 | { |
407 | - switch (segment) | |
571 | + switch (seg) | |
408 | 572 | { |
409 | 573 | case 0x00: /* DMAP translated memory */ |
410 | - segment = 0x10; | |
574 | + seg = 0x10; | |
411 | 575 | break; |
412 | 576 | case 0x01: /* IMAP translated memory */ |
413 | - segment = 0x11; | |
577 | + seg = 0x11; | |
414 | 578 | break; |
415 | 579 | case 0x10: /* On-chip data memory */ |
416 | - segment = 0x02; | |
580 | + seg = 0x02; | |
417 | 581 | break; |
418 | 582 | case 0x11: /* On-chip insn memory */ |
419 | - segment = 0x01; | |
583 | + seg = 0x01; | |
420 | 584 | break; |
421 | 585 | case 0x12: /* Unified memory */ |
422 | - segment = 0x00; | |
586 | + seg = 0x00; | |
423 | 587 | break; |
424 | 588 | } |
425 | 589 | } |
426 | 590 | |
427 | - switch (segment) | |
591 | + switch (seg) | |
428 | 592 | { |
429 | - case 0x10: /* DMAP translated memory */ | |
430 | - { | |
431 | - int byte; | |
432 | - for (byte = 0; byte < size; byte++) | |
433 | - { | |
434 | - uint8 *mem = dmem_addr (addr + byte); | |
435 | - if (mem == NULL) | |
436 | - return byte; | |
437 | - else if (write_p) | |
438 | - *mem = buffer[byte]; | |
439 | - else | |
440 | - buffer[byte] = *mem; | |
441 | - } | |
442 | - return byte; | |
443 | - } | |
593 | + case 0x00: /* Physical unified memory */ | |
594 | + last_from = "phys-unified"; | |
595 | + last_to = "unified"; | |
596 | + phys = SIM_D10V_MEMORY_UNIFIED + off; | |
597 | + if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE) | |
598 | + nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE); | |
599 | + break; | |
444 | 600 | |
445 | - case 0x11: /* IMAP translated memory */ | |
446 | - { | |
447 | - int byte; | |
448 | - for (byte = 0; byte < size; byte++) | |
449 | - { | |
450 | - uint8 *mem = imem_addr (addr + byte); | |
451 | - if (mem == NULL) | |
452 | - return byte; | |
453 | - else if (write_p) | |
454 | - *mem = buffer[byte]; | |
455 | - else | |
456 | - buffer[byte] = *mem; | |
457 | - } | |
458 | - return byte; | |
459 | - } | |
601 | + case 0x01: /* Physical instruction memory */ | |
602 | + last_from = "phys-insn"; | |
603 | + last_to = "chip-insn"; | |
604 | + phys = SIM_D10V_MEMORY_INSN + off; | |
605 | + if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE) | |
606 | + nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE); | |
607 | + break; | |
460 | 608 | |
461 | - case 0x02: /* On-chip data memory */ | |
609 | + case 0x02: /* Physical data memory segment */ | |
610 | + last_from = "phys-data"; | |
611 | + last_to = "chip-data"; | |
612 | + phys = SIM_D10V_MEMORY_DATA + off; | |
613 | + if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE) | |
614 | + nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE); | |
615 | + break; | |
616 | + | |
617 | + case 0x10: /* in logical data address segment */ | |
618 | + nr_bytes = sim_d10v_translate_dmap_addr (off, nr_bytes, &phys, | |
619 | + dmap_register); | |
620 | + break; | |
621 | + | |
622 | + case 0x11: /* in logical instruction address segment */ | |
623 | + nr_bytes = sim_d10v_translate_imap_addr (off, nr_bytes, &phys, | |
624 | + imap_register); | |
625 | + break; | |
626 | + | |
627 | + default: | |
628 | + return 0; | |
629 | + } | |
630 | + | |
631 | + *targ_addr = phys; | |
632 | + return nr_bytes; | |
633 | +} | |
634 | + | |
635 | +/* Return a pointer into the raw buffer designated by phys_addr. It | |
636 | + is assumed that the client has already ensured that the access | |
637 | + isn't going to cross a segment boundary. */ | |
638 | + | |
639 | +uint8 * | |
640 | +map_memory (unsigned phys_addr) | |
641 | +{ | |
642 | + uint8 **memory; | |
643 | + uint8 *raw; | |
644 | + unsigned offset; | |
645 | + int segment = ((phys_addr >> 24) & 0xff); | |
646 | + | |
647 | + switch (segment) | |
648 | + { | |
649 | + | |
650 | + case 0x00: /* Unified memory */ | |
462 | 651 | { |
463 | - addr &= ((1 << DMEM_SIZE) - 1); | |
464 | - if ((addr + size) > (1 << DMEM_SIZE)) | |
465 | - { | |
466 | - (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: data address 0x%x is outside range 0-0x%x.\n", | |
467 | - addr + size - 1, (1 << DMEM_SIZE) - 1); | |
468 | - return (0); | |
469 | - } | |
470 | - memory = State.dmem + addr; | |
652 | + memory = &State.mem.unif[(phys_addr / SEGMENT_SIZE) % UMEM_SEGMENTS]; | |
653 | + last_segname = "umem"; | |
471 | 654 | break; |
472 | 655 | } |
473 | - | |
656 | + | |
474 | 657 | case 0x01: /* On-chip insn memory */ |
475 | 658 | { |
476 | - addr &= ((1 << IMEM_SIZE) - 1); | |
477 | - if ((addr + size) > (1 << IMEM_SIZE)) | |
478 | - { | |
479 | - (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: instruction address 0x%x is outside range 0-0x%x.\n", | |
480 | - addr + size - 1, (1 << IMEM_SIZE) - 1); | |
481 | - return (0); | |
482 | - } | |
483 | - memory = State.imem + addr; | |
659 | + memory = &State.mem.insn[(phys_addr / SEGMENT_SIZE) % IMEM_SEGMENTS]; | |
660 | + last_segname = "imem"; | |
484 | 661 | break; |
485 | 662 | } |
486 | - | |
487 | - case 0x00: /* Unified memory */ | |
663 | + | |
664 | + case 0x02: /* On-chip data memory */ | |
488 | 665 | { |
489 | - int startsegment, startoffset; /* Segment and offset within segment where xfer starts */ | |
490 | - int endsegment, endoffset; /* Segment and offset within segment where xfer ends */ | |
491 | - | |
492 | - startsegment = addr >> UMEM_SIZE; | |
493 | - startoffset = addr & ((1 << UMEM_SIZE) - 1); | |
494 | - endsegment = (addr + size) >> UMEM_SIZE; | |
495 | - endoffset = (addr + size) & ((1 << UMEM_SIZE) - 1); | |
496 | - | |
497 | - /* FIXME: We do not currently implement xfers across segments, | |
498 | - so detect this case and fail gracefully. */ | |
499 | - | |
500 | - if ((startsegment != endsegment) && !((endsegment == (startsegment + 1)) && endoffset == 0)) | |
501 | - { | |
502 | - (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: Unimplemented support for transfers across unified memory segment boundaries\n"); | |
503 | - return (0); | |
504 | - } | |
505 | - if (!State.umem[startsegment]) | |
666 | + if ((phys_addr & 0xff00) == 0xff00) | |
506 | 667 | { |
507 | -#ifdef DEBUG | |
508 | - if ((d10v_debug & DEBUG_MEMSIZE) != 0) | |
668 | + phys_addr = (phys_addr & 0xffff); | |
669 | + if (phys_addr == DMAP2_SHADDOW) | |
509 | 670 | { |
510 | - (*d10v_callback->printf_filtered) (d10v_callback,"Allocating %s bytes unified memory to region %d\n", | |
511 | - add_commas (buffer, sizeof (buffer), (1UL<<IMEM_SIZE)), startsegment); | |
671 | + phys_addr = DMAP2_OFFSET; | |
672 | + last_segname = "dmap"; | |
512 | 673 | } |
513 | -#endif | |
514 | - State.umem[startsegment] = (uint8 *)calloc(1,1<<UMEM_SIZE); | |
515 | - } | |
516 | - if (!State.umem[startsegment]) | |
517 | - { | |
518 | - (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: Memory allocation of 0x%x bytes failed.\n", 1<<UMEM_SIZE); | |
519 | - return (0); | |
674 | + else | |
675 | + last_segname = "reg"; | |
520 | 676 | } |
521 | - memory = State.umem[startsegment] + startoffset; | |
677 | + else | |
678 | + last_segname = "dmem"; | |
679 | + memory = &State.mem.data[(phys_addr / SEGMENT_SIZE) % DMEM_SEGMENTS]; | |
522 | 680 | break; |
523 | 681 | } |
524 | - | |
682 | + | |
525 | 683 | default: |
526 | - { | |
527 | - (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: address 0x%lx is not in valid range\n", (long) addr); | |
528 | - if (old_segment_mapping) | |
529 | - { | |
530 | - (*d10v_callback->printf_filtered) (d10v_callback, "0x00xxxxxx: Logical data address segment (DMAP translated memory)\n"); | |
531 | - (*d10v_callback->printf_filtered) (d10v_callback, "0x01xxxxxx: Logical instruction address segment (IMAP translated memory)\n"); | |
532 | - (*d10v_callback->printf_filtered) (d10v_callback, "0x10xxxxxx: Physical data memory segment (On-chip data memory)\n"); | |
533 | - (*d10v_callback->printf_filtered) (d10v_callback, "0x11xxxxxx: Physical instruction memory segment (On-chip insn memory)\n"); | |
534 | - (*d10v_callback->printf_filtered) (d10v_callback, "0x12xxxxxx: Phisical unified memory segment (Unified memory)\n"); | |
535 | - } | |
536 | - else | |
537 | - { | |
538 | - (*d10v_callback->printf_filtered) (d10v_callback, "0x00xxxxxx: Physical unified memory segment (Unified memory)\n"); | |
539 | - (*d10v_callback->printf_filtered) (d10v_callback, "0x01xxxxxx: Physical instruction memory segment (On-chip insn memory)\n"); | |
540 | - (*d10v_callback->printf_filtered) (d10v_callback, "0x02xxxxxx: Physical data memory segment (On-chip data memory)\n"); | |
541 | - (*d10v_callback->printf_filtered) (d10v_callback, "0x10xxxxxx: Logical data address segment (DMAP translated memory)\n"); | |
542 | - (*d10v_callback->printf_filtered) (d10v_callback, "0x11xxxxxx: Logical instruction address segment (IMAP translated memory)\n"); | |
543 | - } | |
544 | - return (0); | |
545 | - } | |
684 | + /* OOPS! */ | |
685 | + last_segname = "scrap"; | |
686 | + return State.mem.fault; | |
546 | 687 | } |
547 | - | |
548 | - if (write_p) | |
688 | + | |
689 | + if (*memory == NULL) | |
549 | 690 | { |
550 | - memcpy (memory, buffer, size); | |
691 | + *memory = calloc (1, SEGMENT_SIZE); | |
692 | + if (*memory == NULL) | |
693 | + { | |
694 | + (*d10v_callback->printf_filtered) (d10v_callback, "Malloc failed.\n"); | |
695 | + return State.mem.fault; | |
696 | + } | |
551 | 697 | } |
552 | - else | |
698 | + | |
699 | + offset = (phys_addr % SEGMENT_SIZE); | |
700 | + raw = *memory + offset; | |
701 | + return raw; | |
702 | +} | |
703 | + | |
704 | +/* Transfer data to/from simulated memory. Since a bug in either the | |
705 | + simulated program or in gdb or the simulator itself may cause a | |
706 | + bogus address to be passed in, we need to do some sanity checking | |
707 | + on addresses to make sure they are within bounds. When an address | |
708 | + fails the bounds check, treat it as a zero length read/write rather | |
709 | + than aborting the entire run. */ | |
710 | + | |
711 | +static int | |
712 | +xfer_mem (SIM_ADDR virt, | |
713 | + unsigned char *buffer, | |
714 | + int size, | |
715 | + int write_p) | |
716 | +{ | |
717 | + int xfered = 0; | |
718 | + | |
719 | + while (xfered < size) | |
553 | 720 | { |
554 | - memcpy (buffer, memory, size); | |
721 | + uint8 *memory; | |
722 | + unsigned long phys; | |
723 | + int phys_size; | |
724 | + phys_size = sim_d10v_translate_addr (virt, size, | |
725 | + &phys, | |
726 | + dmap_register, | |
727 | + imap_register); | |
728 | + if (phys_size == 0) | |
729 | + return xfered; | |
730 | + | |
731 | + memory = map_memory (phys); | |
732 | + | |
733 | +#ifdef DEBUG | |
734 | + if ((d10v_debug & DEBUG_INSTRUCTION) != 0) | |
735 | + { | |
736 | + (*d10v_callback->printf_filtered) | |
737 | + (d10v_callback, | |
738 | + "sim_%s %d bytes: 0x%08lx (%s) -> 0x%08lx (%s) -> 0x%08lx (%s)\n", | |
739 | + (write_p ? "write" : "read"), | |
740 | + phys_size, virt, last_from, | |
741 | + phys, last_to, | |
742 | + (long) memory, last_segname); | |
743 | + } | |
744 | +#endif | |
745 | + | |
746 | + if (write_p) | |
747 | + { | |
748 | + memcpy (memory, buffer, phys_size); | |
749 | + } | |
750 | + else | |
751 | + { | |
752 | + memcpy (buffer, memory, phys_size); | |
753 | + } | |
754 | + | |
755 | + virt += phys_size; | |
756 | + buffer += phys_size; | |
757 | + xfered += phys_size; | |
555 | 758 | } |
556 | 759 | |
557 | 760 | return size; |
@@ -598,6 +801,9 @@ sim_open (kind, callback, abfd, argv) | ||
598 | 801 | myname = argv[0]; |
599 | 802 | old_segment_mapping = 0; |
600 | 803 | |
804 | + /* NOTE: This argument parsing is only effective when this function | |
805 | + is called by GDB. Standalone argument parsing is handled by | |
806 | + sim/common/run.c. */ | |
601 | 807 | for (p = argv + 1; *p; ++p) |
602 | 808 | { |
603 | 809 | if (strcmp (*p, "-oldseg") == 0) |
@@ -605,6 +811,8 @@ sim_open (kind, callback, abfd, argv) | ||
605 | 811 | #ifdef DEBUG |
606 | 812 | else if (strcmp (*p, "-t") == 0) |
607 | 813 | d10v_debug = DEBUG; |
814 | + else if (strncmp (*p, "-t", 2) == 0) | |
815 | + d10v_debug = atoi (*p + 2); | |
608 | 816 | #endif |
609 | 817 | else |
610 | 818 | (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: unsupported option(s): %s\n",*p); |
@@ -637,8 +845,8 @@ sim_open (kind, callback, abfd, argv) | ||
637 | 845 | } |
638 | 846 | |
639 | 847 | /* reset the processor state */ |
640 | - if (!State.imem) | |
641 | - sim_size(1); | |
848 | + if (!State.mem.data[0]) | |
849 | + sim_size (1); | |
642 | 850 | sim_create_inferior ((SIM_DESC) 1, NULL, NULL, NULL); |
643 | 851 | |
644 | 852 | /* Fudge our descriptor. */ |
@@ -673,84 +881,64 @@ sim_set_profile_size (n) | ||
673 | 881 | (*d10v_callback->printf_filtered) (d10v_callback, "sim_set_profile_size %d\n",n); |
674 | 882 | } |
675 | 883 | |
676 | - | |
677 | 884 | uint8 * |
678 | -dmem_addr( addr ) | |
679 | - uint32 addr; | |
885 | +dmem_addr (uint16 offset) | |
680 | 886 | { |
681 | - int seg; | |
887 | + unsigned long phys; | |
888 | + uint8 *mem; | |
889 | + int phys_size; | |
682 | 890 | |
683 | - addr &= 0xffff; | |
891 | + /* Note: DMEM address range is 0..0x10000. Calling code can compute | |
892 | + things like ``0xfffe + 0x0e60 == 0x10e5d''. Since offset's type | |
893 | + is uint16 this is modulo'ed onto 0x0e5d. */ | |
684 | 894 | |
685 | - if (addr > 0xbfff) | |
895 | + phys_size = sim_d10v_translate_dmap_addr (offset, 1, &phys, | |
896 | + dmap_register); | |
897 | + if (phys_size == 0) | |
686 | 898 | { |
687 | - if ( (addr & 0xfff0) != 0xff00) | |
688 | - { | |
689 | - (*d10v_callback->printf_filtered) (d10v_callback, "Data address 0x%lx is in I/O space, pc = 0x%lx.\n", | |
690 | - (long)addr, (long)decode_pc ()); | |
691 | - State.exception = SIGBUS; | |
692 | - } | |
693 | - | |
694 | - return State.dmem + addr; | |
899 | + mem = State.mem.fault; | |
695 | 900 | } |
696 | - | |
697 | - if (addr > 0x7fff) | |
698 | - { | |
699 | - if (DMAP & 0x1000) | |
700 | - { | |
701 | - /* instruction memory */ | |
702 | - return (DMAP & 0xf) * 0x4000 + State.imem + (addr - 0x8000); | |
703 | - } | |
704 | - else | |
705 | - { | |
706 | - /* unified memory */ | |
707 | - /* this is ugly because we allocate unified memory in 128K segments and */ | |
708 | - /* dmap addresses 16k segments */ | |
709 | - seg = (DMAP & 0x3ff) >> 3; | |
710 | - if (State.umem[seg] == NULL) | |
711 | - { | |
901 | + else | |
902 | + mem = map_memory (phys); | |
712 | 903 | #ifdef DEBUG |
713 | - (*d10v_callback->printf_filtered) (d10v_callback,"Allocating %d bytes unified memory to region %d\n", 1<<UMEM_SIZE, seg); | |
714 | -#endif | |
715 | - State.umem[seg] = (uint8 *)calloc(1,1<<UMEM_SIZE); | |
716 | - if (!State.umem[seg]) | |
717 | - { | |
718 | - (*d10v_callback->printf_filtered) (d10v_callback, | |
719 | - "ERROR: alloc failed. unified memory region %d unmapped, pc = 0x%lx\n", | |
720 | - seg, (long)decode_pc ()); | |
721 | - State.exception = SIGBUS; | |
722 | - } | |
723 | - } | |
724 | - return State.umem[seg] + (DMAP & 7) * 0x4000 + (addr - 0x8000); | |
725 | - } | |
904 | + if ((d10v_debug & DEBUG_MEMORY)) | |
905 | + { | |
906 | + (*d10v_callback->printf_filtered) | |
907 | + (d10v_callback, | |
908 | + "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n", | |
909 | + offset, last_from, | |
910 | + phys, phys_size, last_to, | |
911 | + (long) mem, last_segname); | |
726 | 912 | } |
727 | - return State.dmem + addr; | |
913 | +#endif | |
914 | + return mem; | |
728 | 915 | } |
729 | 916 | |
730 | - | |
731 | 917 | uint8 * |
732 | -imem_addr (uint32 pc) | |
918 | +imem_addr (uint32 offset) | |
733 | 919 | { |
734 | - uint16 imap; | |
735 | - | |
736 | - if (pc & 0x20000) | |
737 | - imap = IMAP1; | |
738 | - else | |
739 | - imap = IMAP0; | |
740 | - | |
741 | - if (imap & 0x1000) | |
742 | - return State.imem + pc; | |
743 | - | |
744 | - if (State.umem[imap & 0xff] == NULL) | |
745 | - return 0; | |
746 | - | |
747 | - /* Discard upper bit(s) of PC in case IMAP1 selects unified memory. */ | |
748 | - pc &= (1 << UMEM_SIZE) - 1; | |
749 | - | |
750 | - return State.umem[imap & 0xff] + pc; | |
920 | + unsigned long phys; | |
921 | + uint8 *mem; | |
922 | + int phys_size = sim_d10v_translate_imap_addr (offset, 1, &phys, imap_register); | |
923 | + if (phys_size == 0) | |
924 | + { | |
925 | + return State.mem.fault; | |
926 | + } | |
927 | + mem = map_memory (phys); | |
928 | +#ifdef DEBUG | |
929 | + if ((d10v_debug & DEBUG_MEMORY)) | |
930 | + { | |
931 | + (*d10v_callback->printf_filtered) | |
932 | + (d10v_callback, | |
933 | + "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n", | |
934 | + offset, last_from, | |
935 | + phys, phys_size, last_to, | |
936 | + (long) mem, last_segname); | |
937 | + } | |
938 | +#endif | |
939 | + return mem; | |
751 | 940 | } |
752 | 941 | |
753 | - | |
754 | 942 | static int stop_simulator = 0; |
755 | 943 | |
756 | 944 | int |
@@ -779,7 +967,7 @@ sim_resume (sd, step, siggnal) | ||
779 | 967 | do |
780 | 968 | { |
781 | 969 | iaddr = imem_addr ((uint32)PC << 2); |
782 | - if (iaddr == NULL) | |
970 | + if (iaddr == State.mem.fault) | |
783 | 971 | { |
784 | 972 | State.exception = SIGBUS; |
785 | 973 | break; |
@@ -990,7 +1178,7 @@ sim_create_inferior (sd, abfd, argv, env) | ||
990 | 1178 | bfd_vma start_address; |
991 | 1179 | |
992 | 1180 | /* reset all state information */ |
993 | - memset (&State.regs, 0, (int)&State.imem - (int)&State.regs[0]); | |
1181 | + memset (&State.regs, 0, (int)&State.mem - (int)&State.regs); | |
994 | 1182 | |
995 | 1183 | if (argv) |
996 | 1184 | { |
@@ -1022,19 +1210,28 @@ sim_create_inferior (sd, abfd, argv, env) | ||
1022 | 1210 | #endif |
1023 | 1211 | SET_CREG (PC_CR, start_address >> 2); |
1024 | 1212 | |
1025 | - /* cpu resets imap0 to 0 and imap1 to 0x7f, but D10V-EVA board */ | |
1026 | - /* resets imap0 and imap1 to 0x1000. */ | |
1213 | + /* cpu resets imap0 to 0 and imap1 to 0x7f, but D10V-EVA board | |
1214 | + initializes imap0 and imap1 to 0x1000 as part of its ROM | |
1215 | + initialization. */ | |
1027 | 1216 | if (old_segment_mapping) |
1028 | 1217 | { |
1029 | - SET_IMAP0 (0x0000); | |
1030 | - SET_IMAP1 (0x007f); | |
1031 | - SET_DMAP (0x0000); | |
1218 | + /* External memory startup. This is the HARD reset state. */ | |
1219 | + set_imap_register (0, 0x0000); | |
1220 | + set_imap_register (1, 0x007f); | |
1221 | + set_dmap_register (0, 0x2000); | |
1222 | + set_dmap_register (1, 0x2000); | |
1223 | + set_dmap_register (2, 0x0000); /* Old DMAP */ | |
1224 | + set_dmap_register (3, 0x0000); | |
1032 | 1225 | } |
1033 | 1226 | else |
1034 | 1227 | { |
1035 | - SET_IMAP0 (0x1000); | |
1036 | - SET_IMAP1 (0x1000); | |
1037 | - SET_DMAP(0); | |
1228 | + /* Internal memory startup. This is the ROM intialized state. */ | |
1229 | + set_imap_register (0, 0x1000); | |
1230 | + set_imap_register (1, 0x1000); | |
1231 | + set_dmap_register (0, 0x2000); | |
1232 | + set_dmap_register (1, 0x2000); | |
1233 | + set_dmap_register (2, 0x0000); /* Old DMAP, Value is not 0x2000 */ | |
1234 | + set_dmap_register (3, 0x0000); | |
1038 | 1235 | } |
1039 | 1236 | |
1040 | 1237 | SLOT_FLUSH (); |
@@ -1088,19 +1285,56 @@ sim_fetch_register (sd, rn, memory, length) | ||
1088 | 1285 | unsigned char *memory; |
1089 | 1286 | int length; |
1090 | 1287 | { |
1091 | - if (rn > 34) | |
1092 | - WRITE_64 (memory, ACC (rn-35)); | |
1093 | - else if (rn == 32) | |
1094 | - WRITE_16 (memory, IMAP0); | |
1095 | - else if (rn == 33) | |
1096 | - WRITE_16 (memory, IMAP1); | |
1097 | - else if (rn == 34) | |
1098 | - WRITE_16 (memory, DMAP); | |
1099 | - else if (rn >= 16) | |
1100 | - WRITE_16 (memory, CREG (rn - 16)); | |
1288 | + int size; | |
1289 | + if (rn < 0) | |
1290 | + size = 0; | |
1291 | + else if (rn >= SIM_D10V_R0_REGNUM | |
1292 | + && rn < SIM_D10V_R0_REGNUM + SIM_D10V_NR_R_REGS) | |
1293 | + { | |
1294 | + WRITE_16 (memory, GPR (rn - SIM_D10V_R0_REGNUM)); | |
1295 | + size = 2; | |
1296 | + } | |
1297 | + else if (rn >= SIM_D10V_CR0_REGNUM | |
1298 | + && rn < SIM_D10V_CR0_REGNUM + SIM_D10V_NR_CR_REGS) | |
1299 | + { | |
1300 | + WRITE_16 (memory, CREG (rn - SIM_D10V_CR0_REGNUM)); | |
1301 | + size = 2; | |
1302 | + } | |
1303 | + else if (rn >= SIM_D10V_A0_REGNUM | |
1304 | + && rn < SIM_D10V_A0_REGNUM + SIM_D10V_NR_A_REGS) | |
1305 | + { | |
1306 | + WRITE_64 (memory, ACC (rn - SIM_D10V_A0_REGNUM)); | |
1307 | + size = 8; | |
1308 | + } | |
1309 | + else if (rn == SIM_D10V_SPI_REGNUM) | |
1310 | + { | |
1311 | + /* PSW_SM indicates that the current SP is the USER | |
1312 | + stack-pointer. */ | |
1313 | + WRITE_16 (memory, spi_register ()); | |
1314 | + size = 2; | |
1315 | + } | |
1316 | + else if (rn == SIM_D10V_SPU_REGNUM) | |
1317 | + { | |
1318 | + /* PSW_SM indicates that the current SP is the USER | |
1319 | + stack-pointer. */ | |
1320 | + WRITE_16 (memory, spu_register ()); | |
1321 | + size = 2; | |
1322 | + } | |
1323 | + else if (rn >= SIM_D10V_IMAP0_REGNUM | |
1324 | + && rn < SIM_D10V_IMAP0_REGNUM + SIM_D10V_NR_IMAP_REGS) | |
1325 | + { | |
1326 | + WRITE_16 (memory, imap_register (rn - SIM_D10V_IMAP0_REGNUM)); | |
1327 | + size = 2; | |
1328 | + } | |
1329 | + else if (rn >= SIM_D10V_DMAP0_REGNUM | |
1330 | + && rn < SIM_D10V_DMAP0_REGNUM + SIM_D10V_NR_DMAP_REGS) | |
1331 | + { | |
1332 | + WRITE_16 (memory, dmap_register (rn - SIM_D10V_DMAP0_REGNUM)); | |
1333 | + size = 2; | |
1334 | + } | |
1101 | 1335 | else |
1102 | - WRITE_16 (memory, GPR (rn)); | |
1103 | - return -1; | |
1336 | + size = 0; | |
1337 | + return size; | |
1104 | 1338 | } |
1105 | 1339 | |
1106 | 1340 | int |
@@ -1110,20 +1344,55 @@ sim_store_register (sd, rn, memory, length) | ||
1110 | 1344 | unsigned char *memory; |
1111 | 1345 | int length; |
1112 | 1346 | { |
1113 | - if (rn > 34) | |
1114 | - SET_ACC (rn-35, READ_64 (memory) & MASK40); | |
1115 | - else if (rn == 34) | |
1116 | - SET_DMAP( READ_16(memory) ); | |
1117 | - else if (rn == 33) | |
1118 | - SET_IMAP1( READ_16(memory) ); | |
1119 | - else if (rn == 32) | |
1120 | - SET_IMAP0( READ_16(memory) ); | |
1121 | - else if (rn >= 16) | |
1122 | - SET_CREG (rn - 16, READ_16 (memory)); | |
1347 | + int size; | |
1348 | + if (rn < 0) | |
1349 | + size = 0; | |
1350 | + else if (rn >= SIM_D10V_R0_REGNUM | |
1351 | + && rn < SIM_D10V_R0_REGNUM + SIM_D10V_NR_R_REGS) | |
1352 | + { | |
1353 | + SET_GPR (rn - SIM_D10V_R0_REGNUM, READ_16 (memory)); | |
1354 | + size = 2; | |
1355 | + } | |
1356 | + else if (rn >= SIM_D10V_CR0_REGNUM | |
1357 | + && rn < SIM_D10V_CR0_REGNUM + SIM_D10V_NR_CR_REGS) | |
1358 | + { | |
1359 | + SET_CREG (rn - SIM_D10V_CR0_REGNUM, READ_16 (memory)); | |
1360 | + size = 2; | |
1361 | + } | |
1362 | + else if (rn >= SIM_D10V_A0_REGNUM | |
1363 | + && rn < SIM_D10V_A0_REGNUM + SIM_D10V_NR_A_REGS) | |
1364 | + { | |
1365 | + SET_ACC (rn - SIM_D10V_A0_REGNUM, READ_64 (memory) & MASK40); | |
1366 | + size = 8; | |
1367 | + } | |
1368 | + else if (rn == SIM_D10V_SPI_REGNUM) | |
1369 | + { | |
1370 | + /* PSW_SM indicates that the current SP is the USER | |
1371 | + stack-pointer. */ | |
1372 | + set_spi_register (READ_16 (memory)); | |
1373 | + size = 2; | |
1374 | + } | |
1375 | + else if (rn == SIM_D10V_SPU_REGNUM) | |
1376 | + { | |
1377 | + set_spu_register (READ_16 (memory)); | |
1378 | + size = 2; | |
1379 | + } | |
1380 | + else if (rn >= SIM_D10V_IMAP0_REGNUM | |
1381 | + && rn < SIM_D10V_IMAP0_REGNUM + SIM_D10V_NR_IMAP_REGS) | |
1382 | + { | |
1383 | + set_imap_register (rn - SIM_D10V_IMAP0_REGNUM, READ_16(memory)); | |
1384 | + size = 2; | |
1385 | + } | |
1386 | + else if (rn >= SIM_D10V_DMAP0_REGNUM | |
1387 | + && rn < SIM_D10V_DMAP0_REGNUM + SIM_D10V_NR_DMAP_REGS) | |
1388 | + { | |
1389 | + set_dmap_register (rn - SIM_D10V_DMAP0_REGNUM, READ_16(memory)); | |
1390 | + size = 2; | |
1391 | + } | |
1123 | 1392 | else |
1124 | - SET_GPR (rn, READ_16 (memory)); | |
1393 | + size = 0; | |
1125 | 1394 | SLOT_FLUSH (); |
1126 | - return -1; | |
1395 | + return size; | |
1127 | 1396 | } |
1128 | 1397 | |
1129 | 1398 |
@@ -56,10 +56,13 @@ enum { | ||
56 | 56 | | PSW_F0_BIT |
57 | 57 | | PSW_F1_BIT |
58 | 58 | | PSW_C_BIT), |
59 | + /* The following bits in the PSW _can't_ be set by instructions such | |
60 | + as mvtc. */ | |
61 | + PSW_HW_MASK = (PSW_MASK | PSW_DM_BIT) | |
59 | 62 | }; |
60 | 63 | |
61 | 64 | reg_t |
62 | -move_to_cr (int cr, reg_t mask, reg_t val) | |
65 | +move_to_cr (int cr, reg_t mask, reg_t val, int psw_hw_p) | |
63 | 66 | { |
64 | 67 | /* A MASK bit is set when the corresponding bit in the CR should |
65 | 68 | be left alone */ |
@@ -67,13 +70,18 @@ move_to_cr (int cr, reg_t mask, reg_t val) | ||
67 | 70 | switch (cr) |
68 | 71 | { |
69 | 72 | case PSW_CR: |
70 | - val &= PSW_MASK; | |
73 | + if (psw_hw_p) | |
74 | + val &= PSW_HW_MASK; | |
75 | + else | |
76 | + val &= PSW_MASK; | |
71 | 77 | if ((mask & PSW_SM_BIT) == 0) |
72 | 78 | { |
73 | - int new_sm = (val & PSW_SM_BIT) != 0; | |
74 | - SET_HELD_SP (PSW_SM, GPR (SP_IDX)); /* save old SP */ | |
75 | - if (PSW_SM != new_sm) | |
76 | - SET_GPR (SP_IDX, HELD_SP (new_sm)); /* restore new SP */ | |
79 | + int new_psw_sm = (val & PSW_SM_BIT) != 0; | |
80 | + /* save old SP */ | |
81 | + SET_HELD_SP (PSW_SM, GPR (SP_IDX)); | |
82 | + if (PSW_SM != new_psw_sm) | |
83 | + /* restore new SP */ | |
84 | + SET_GPR (SP_IDX, HELD_SP (new_psw_sm)); | |
77 | 85 | } |
78 | 86 | if ((mask & (PSW_ST_BIT | PSW_FX_BIT)) == 0) |
79 | 87 | { |
@@ -91,7 +99,11 @@ move_to_cr (int cr, reg_t mask, reg_t val) | ||
91 | 99 | break; |
92 | 100 | case BPSW_CR: |
93 | 101 | case DPSW_CR: |
94 | - val &= PSW_MASK; | |
102 | + /* Just like PSW, mask things like DM out. */ | |
103 | + if (psw_hw_p) | |
104 | + val &= PSW_HW_MASK; | |
105 | + else | |
106 | + val &= PSW_MASK; | |
95 | 107 | break; |
96 | 108 | case MOD_S_CR: |
97 | 109 | case MOD_E_CR: |
@@ -1096,7 +1108,7 @@ OP_5F20 () | ||
1096 | 1108 | trace_input ("dbt", OP_VOID, OP_VOID, OP_VOID); |
1097 | 1109 | SET_DPC (PC + 1); |
1098 | 1110 | SET_DPSW (PSW); |
1099 | - SET_PSW (PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)); | |
1111 | + SET_HW_PSW (PSW_DM_BIT | (PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT))); | |
1100 | 1112 | JMP (DBT_VECTOR_START); |
1101 | 1113 | trace_output_void (); |
1102 | 1114 | } |
@@ -1,3 +1,8 @@ | ||
1 | +1999-11-11 Andrew Haley <aph@cygnus.com> | |
2 | + | |
3 | + * interp.c (decode_coproc): Correctly handle DMFC0 and DMTC0 | |
4 | + instructions. | |
5 | + | |
1 | 6 | Thu Sep 9 15:12:08 1999 Geoffrey Keating <geoffk@cygnus.com> |
2 | 7 | |
3 | 8 | * mips.igen (MULT): Correct previous mis-applied patch. |
@@ -3124,9 +3124,14 @@ decode_coproc (SIM_DESC sd, | ||
3124 | 3124 | CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii) |
3125 | 3125 | ERET Exception return (VR4100 = 01000010000000000000000000011000) |
3126 | 3126 | */ |
3127 | - if (((code == 0x00) || (code == 0x04)) && tail == 0) | |
3127 | + if (((code == 0x00) || (code == 0x04) /* MFC0 / MTC0 */ | |
3128 | + || (code == 0x01) || (code == 0x05)) /* DMFC0 / DMTC0 */ | |
3129 | + && tail == 0) | |
3128 | 3130 | { |
3129 | - /* M[TF]C0 - 32 bit word */ | |
3131 | + /* Clear double/single coprocessor move bit. */ | |
3132 | + code &= ~1; | |
3133 | + | |
3134 | + /* M[TF]C0 (32 bits) | DM[TF]C0 (64 bits) */ | |
3130 | 3135 | |
3131 | 3136 | switch (rd) /* NOTEs: Standard CP0 registers */ |
3132 | 3137 | { |
@@ -1,3 +1,12 @@ | ||
1 | +Fri Oct 29 18:36:34 1999 Andrew Cagney <cagney@b1.cygnus.com> | |
2 | + | |
3 | + * t-mvtc.s: Check that the user can not modify the DM bit in the | |
4 | + BPSW or DPSW. | |
5 | + | |
6 | +Thu Oct 28 01:47:26 1999 Andrew Cagney <cagney@b1.cygnus.com> | |
7 | + | |
8 | + * t-mvtc.s: Update. Check that user can not modify DM bit. | |
9 | + | |
1 | 10 | Wed Sep 8 19:34:55 MDT 1999 Diego Novillo <dnovillo@cygnus.com> |
2 | 11 | |
3 | 12 | * t-ld-st.s: New file. |
@@ -17,7 +17,7 @@ | ||
17 | 17 | checkpsw2 4 PSW_DB |
18 | 18 | |
19 | 19 | loadpsw2 PSW_DM |
20 | - checkpsw2 5 PSW_DM | |
20 | + checkpsw2 5 0 ;; PSW_DM | |
21 | 21 | |
22 | 22 | loadpsw2 PSW_IE |
23 | 23 | checkpsw2 6 PSW_IE |
@@ -65,17 +65,65 @@ | ||
65 | 65 | mvfc r7, cr11 |
66 | 66 | check 18 r7 0xbeee |
67 | 67 | |
68 | -;;; Check that certain bits of the DPSW and BPSW are hardwired to zero | |
68 | +;;; Check that certain bits of the PSW, DPSW and BPSW are hardwired to zero | |
69 | 69 | |
70 | +psw_ffff: | |
71 | + ldi r6, 0xffff | |
72 | + mvtc r6, psw | |
73 | + mvfc r7, psw | |
74 | + check 18 r7 0xb7cd | |
75 | + | |
76 | +bpsw_ffff: | |
70 | 77 | ldi r6, 0xffff |
71 | 78 | mvtc r6, bpsw |
72 | 79 | mvfc r7, bpsw |
73 | - check 18 r7 0xbfcd | |
80 | + check 18 r7 0xb7cd | |
74 | 81 | |
82 | +dpsw_ffff: | |
75 | 83 | ldi r6, 0xffff |
76 | 84 | mvtc r6, dpsw |
77 | 85 | mvfc r7, dpsw |
78 | - check 18 r7 0xbfcd | |
86 | + check 18 r7 0xb7cd | |
87 | + | |
88 | +;;; Another check. Very similar | |
89 | + | |
90 | +psw_dfff: | |
91 | + ldi r6, 0xdfff | |
92 | + mvtc r6, psw | |
93 | + mvfc r7, psw | |
94 | + check 18 r7 0x97cd | |
95 | + | |
96 | +bpsw_dfff: | |
97 | + ldi r6, 0xdfff | |
98 | + mvtc r6, bpsw | |
99 | + mvfc r7, bpsw | |
100 | + check 18 r7 0x97cd | |
101 | + | |
102 | +dpsw_dfff: | |
103 | + ldi r6, 0xdfff | |
104 | + mvtc r6, dpsw | |
105 | + mvfc r7, dpsw | |
106 | + check 18 r7 0x97cd | |
107 | + | |
108 | +;;; And again. | |
109 | + | |
110 | +psw_8005: | |
111 | + ldi r6, 0x8005 | |
112 | + mvtc r6, psw | |
113 | + mvfc r7, psw | |
114 | + check 18 r7 0x8005 | |
115 | + | |
116 | +bpsw_8005: | |
117 | + ldi r6, 0x8005 | |
118 | + mvtc r6, bpsw | |
119 | + mvfc r7, bpsw | |
120 | + check 18 r7 0x8005 | |
121 | + | |
122 | +dpsw_8005: | |
123 | + ldi r6, 0x8005 | |
124 | + mvtc r6, dpsw | |
125 | + mvfc r7, dpsw | |
126 | + check 18 r7 0x8005 | |
79 | 127 | |
80 | 128 | |
81 | 129 | exit0 |