1 /* The IGEN simulator generator for GDB, the GNU Debugger. 2 3 Copyright 2002-2020 Free Software Foundation, Inc. 4 5 Contributed by Andrew Cagney. 6 7 This file is part of GDB. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 3 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 21 22 23 24 #include "misc.h" 25 #include "lf.h" 26 #include "table.h" 27 #include "filter.h" 28 #include "igen.h" 29 30 #include "ld-insn.h" 31 #include "ld-decode.h" 32 33 #include "gen.h" 34 35 #include "gen-semantics.h" 36 #include "gen-icache.h" 37 #include "gen-idecode.h" 38 39 40 static void 41 print_semantic_function_header (lf *file, 42 const char *basename, 43 const char *format_name, 44 opcode_bits *expanded_bits, 45 int is_function_definition, 46 int nr_prefetched_words) 47 { 48 int indent; 49 lf_printf (file, "\n"); 50 lf_print__function_type_function (file, print_semantic_function_type, 51 "EXTERN_SEMANTICS", 52 (is_function_definition ? "\n" : " ")); 53 indent = print_function_name (file, 54 basename, 55 format_name, 56 NULL, 57 expanded_bits, 58 function_name_prefix_semantics); 59 if (is_function_definition) 60 { 61 indent += lf_printf (file, " "); 62 lf_indent (file, +indent); 63 } 64 else 65 { 66 lf_printf (file, "\n"); 67 } 68 lf_printf (file, "("); 69 lf_indent (file, +1); 70 print_semantic_function_formal (file, nr_prefetched_words); 71 lf_indent (file, -1); 72 lf_printf (file, ")"); 73 if (is_function_definition) 74 { 75 lf_indent (file, -indent); 76 } 77 else 78 { 79 lf_printf (file, ";"); 80 } 81 lf_printf (file, "\n"); 82 } 83 84 void 85 print_semantic_declaration (lf *file, 86 insn_entry * insn, 87 opcode_bits *expanded_bits, 88 insn_opcodes *opcodes, int nr_prefetched_words) 89 { 90 print_semantic_function_header (file, 91 insn->name, 92 insn->format_name, 93 expanded_bits, 94 0 /* is not function definition */ , 95 nr_prefetched_words); 96 } 97 98 99 100 /* generate the semantics.c file */ 101 102 103 void 104 print_idecode_invalid (lf *file, const char *result, invalid_type type) 105 { 106 const char *name; 107 switch (type) 108 { 109 default: 110 name = "unknown"; 111 break; 112 case invalid_illegal: 113 name = "illegal"; 114 break; 115 case invalid_fp_unavailable: 116 name = "fp_unavailable"; 117 break; 118 case invalid_wrong_slot: 119 name = "wrong_slot"; 120 break; 121 } 122 if (options.gen.code == generate_jumps) 123 { 124 lf_printf (file, "goto %s_%s;\n", 125 (options.gen.icache ? "icache" : "semantic"), name); 126 } 127 else if (options.gen.icache) 128 { 129 lf_printf (file, "%s %sicache_%s (", result, 130 options.module.global.prefix.l, name); 131 print_icache_function_actual (file, 0); 132 lf_printf (file, ");\n"); 133 } 134 else 135 { 136 lf_printf (file, "%s %ssemantic_%s (", result, 137 options.module.global.prefix.l, name); 138 print_semantic_function_actual (file, 0); 139 lf_printf (file, ");\n"); 140 } 141 } 142 143 144 void 145 print_semantic_body (lf *file, 146 insn_entry * instruction, 147 opcode_bits *expanded_bits, insn_opcodes *opcodes) 148 { 149 /* validate the instruction, if a cache this has already been done */ 150 if (!options.gen.icache) 151 { 152 print_idecode_validate (file, instruction, opcodes); 153 } 154 155 print_itrace (file, instruction, 0 /*put_value_in_cache */ ); 156 157 /* generate the instruction profile call - this is delayed until 158 after the instruction has been verified. The count macro 159 generated is prefixed by ITABLE_PREFIX */ 160 { 161 lf_printf (file, "\n"); 162 lf_indent_suppress (file); 163 lf_printf (file, "#if defined (%sPROFILE_COUNT_INSN)\n", 164 options.module.itable.prefix.u); 165 lf_printf (file, "%sPROFILE_COUNT_INSN (CPU, CIA, MY_INDEX);\n", 166 options.module.itable.prefix.u); 167 lf_indent_suppress (file); 168 lf_printf (file, "#endif\n"); 169 } 170 171 /* generate the model call - this is delayed until after the 172 instruction has been verified */ 173 { 174 lf_printf (file, "\n"); 175 lf_indent_suppress (file); 176 lf_printf (file, "#if defined (WITH_MON)\n"); 177 lf_printf (file, "/* monitoring: */\n"); 178 lf_printf (file, "if (WITH_MON & MONITOR_INSTRUCTION_ISSUE)\n"); 179 lf_printf (file, " mon_issue ("); 180 print_function_name (file, 181 instruction->name, 182 instruction->format_name, 183 NULL, NULL, function_name_prefix_itable); 184 lf_printf (file, ", cpu, cia);\n"); 185 lf_indent_suppress (file); 186 lf_printf (file, "#endif\n"); 187 lf_printf (file, "\n"); 188 } 189 190 /* determine the new instruction address */ 191 { 192 lf_printf (file, "/* keep the next instruction address handy */\n"); 193 if (options.gen.nia == nia_is_invalid) 194 { 195 lf_printf (file, "nia = %sINVALID_INSTRUCTION_ADDRESS;\n", 196 options.module.global.prefix.u); 197 } 198 else 199 { 200 int nr_immeds = instruction->nr_words - 1; 201 if (options.gen.delayed_branch) 202 { 203 if (nr_immeds > 0) 204 { 205 lf_printf (file, "cia.dp += %d * %d; %s\n", 206 options.insn_bit_size / 8, nr_immeds, 207 "/* skip dp immeds */"); 208 } 209 lf_printf (file, "nia.ip = cia.dp; %s\n", 210 "/* instruction pointer */"); 211 lf_printf (file, "nia.dp = cia.dp + %d; %s\n", 212 options.insn_bit_size / 8, 213 "/* delayed-slot pointer */"); 214 } 215 else 216 { 217 if (nr_immeds > 0) 218 { 219 lf_printf (file, "nia = cia + %d * (%d + 1); %s\n", 220 options.insn_bit_size / 8, nr_immeds, 221 "/* skip immeds as well */"); 222 223 } 224 else 225 { 226 lf_printf (file, "nia = cia + %d;\n", 227 options.insn_bit_size / 8); 228 } 229 } 230 } 231 } 232 233 /* if conditional, generate code to verify that the instruction 234 should be issued */ 235 if (filter_is_member (instruction->options, "c") 236 || options.gen.conditional_issue) 237 { 238 lf_printf (file, "\n"); 239 lf_printf (file, "/* execute only if conditional passes */\n"); 240 lf_printf (file, "if (IS_CONDITION_OK)\n"); 241 lf_printf (file, " {\n"); 242 lf_indent (file, +4); 243 /* FIXME - need to log a conditional failure */ 244 } 245 246 /* Architecture expects a REG to be zero. Instead of having to 247 check every read to see if it is refering to that REG just zap it 248 at the start of every instruction */ 249 if (options.gen.zero_reg) 250 { 251 lf_printf (file, "\n"); 252 lf_printf (file, "/* Architecture expects REG to be zero */\n"); 253 lf_printf (file, "GPR_CLEAR(%d);\n", options.gen.zero_reg_nr); 254 } 255 256 /* generate the code (or at least something */ 257 lf_printf (file, "\n"); 258 lf_printf (file, "/* semantics: */\n"); 259 if (instruction->code != NULL) 260 { 261 /* true code */ 262 lf_printf (file, "{\n"); 263 lf_indent (file, +2); 264 lf_print__line_ref (file, instruction->code->line); 265 table_print_code (file, instruction->code); 266 lf_indent (file, -2); 267 lf_printf (file, "}\n"); 268 lf_print__internal_ref (file); 269 } 270 else if (filter_is_member (instruction->options, "nop")) 271 { 272 lf_print__internal_ref (file); 273 } 274 else 275 { 276 const char *prefix = "sim_engine_abort ("; 277 int indent = strlen (prefix); 278 /* abort so it is implemented now */ 279 lf_print__line_ref (file, instruction->line); 280 lf_printf (file, "%sSD, CPU, cia, \\\n", prefix); 281 lf_indent (file, +indent); 282 lf_printf (file, "\"%s:%d:0x%%08lx:%%s unimplemented\\n\", \\\n", 283 filter_filename (instruction->line->file_name), 284 instruction->line->line_nr); 285 lf_printf (file, "(long) CIA, \\\n"); 286 lf_printf (file, "%sitable[MY_INDEX].name);\n", 287 options.module.itable.prefix.l); 288 lf_indent (file, -indent); 289 lf_print__internal_ref (file); 290 } 291 292 /* Close off the conditional execution */ 293 if (filter_is_member (instruction->options, "c") 294 || options.gen.conditional_issue) 295 { 296 lf_indent (file, -4); 297 lf_printf (file, " }\n"); 298 } 299 } 300 301 static void 302 print_c_semantic (lf *file, 303 insn_entry * instruction, 304 opcode_bits *expanded_bits, 305 insn_opcodes *opcodes, 306 cache_entry *cache_rules, int nr_prefetched_words) 307 { 308 309 lf_printf (file, "{\n"); 310 lf_indent (file, +2); 311 312 print_my_defines (file, 313 instruction->name, 314 instruction->format_name, expanded_bits); 315 lf_printf (file, "\n"); 316 print_icache_body (file, 317 instruction, 318 expanded_bits, 319 cache_rules, 320 (options.gen.direct_access 321 ? define_variables 322 : declare_variables), 323 (options.gen.icache 324 ? get_values_from_icache 325 : do_not_use_icache), nr_prefetched_words); 326 327 lf_printf (file, "%sinstruction_address nia;\n", 328 options.module.global.prefix.l); 329 print_semantic_body (file, instruction, expanded_bits, opcodes); 330 lf_printf (file, "return nia;\n"); 331 332 /* generate something to clean up any #defines created for the cache */ 333 if (options.gen.direct_access) 334 { 335 print_icache_body (file, 336 instruction, 337 expanded_bits, 338 cache_rules, 339 undef_variables, 340 (options.gen.icache 341 ? get_values_from_icache 342 : do_not_use_icache), nr_prefetched_words); 343 } 344 345 lf_indent (file, -2); 346 lf_printf (file, "}\n"); 347 } 348 349 static void 350 print_c_semantic_function (lf *file, 351 insn_entry * instruction, 352 opcode_bits *expanded_bits, 353 insn_opcodes *opcodes, 354 cache_entry *cache_rules, int nr_prefetched_words) 355 { 356 /* build the semantic routine to execute the instruction */ 357 print_semantic_function_header (file, 358 instruction->name, 359 instruction->format_name, 360 expanded_bits, 361 1 /*is-function-definition */ , 362 nr_prefetched_words); 363 print_c_semantic (file, 364 instruction, 365 expanded_bits, opcodes, cache_rules, nr_prefetched_words); 366 } 367 368 void 369 print_semantic_definition (lf *file, 370 insn_entry * insn, 371 opcode_bits *expanded_bits, 372 insn_opcodes *opcodes, 373 cache_entry *cache_rules, int nr_prefetched_words) 374 { 375 print_c_semantic_function (file, 376 insn, 377 expanded_bits, 378 opcodes, cache_rules, nr_prefetched_words); 379 } 380