Changeset 609 for branches/GNU/src/binutils/opcodes/d30v-dis.c
- Timestamp:
- Aug 16, 2003, 6:59:22 PM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/GNU/src/binutils/opcodes/d30v-dis.c
-
Property cvs2svn:cvs-rev
changed from
1.1
to1.1.1.2
r608 r609 1 1 /* Disassemble D30V instructions. 2 Copyright 1997, 1998, 2000 Free Software Foundation, Inc.2 Copyright 1997, 1998, 2000, 2001 Free Software Foundation, Inc. 3 3 4 4 This program is free software; you can redistribute it and/or modify … … 18 18 #include <stdio.h> 19 19 #include "sysdep.h" 20 #include "opcode/d30v.h" 20 #include "opcode/d30v.h" 21 21 #include "dis-asm.h" 22 22 #include "opintl.h" … … 24 24 #define PC_MASK 0xFFFFFFFF 25 25 26 static int lookup_opcode PARAMS (( struct d30v_insn *insn, long num, int is_long));27 static void print_insn PARAMS (( struct disassemble_info *info, bfd_vma memaddr, long long num,28 struct d30v_insn *insn, int is_long, int show_ext 29 static int extract_value PARAMS (( long long num, struct d30v_operand *oper, int is_long));30 31 int 26 static int lookup_opcode PARAMS ((struct d30v_insn *insn, long num, int is_long)); 27 static void print_insn PARAMS ((struct disassemble_info *info, bfd_vma memaddr, long long num, 28 struct d30v_insn *insn, int is_long, int show_ext)); 29 static int extract_value PARAMS ((long long num, struct d30v_operand *oper, int is_long)); 30 31 int 32 32 print_insn_d30v (memaddr, info) 33 33 bfd_vma memaddr; … … 36 36 int status, result; 37 37 bfd_byte buffer[12]; 38 unsigned long in1, in2;38 unsigned long in1, in2; 39 39 struct d30v_insn insn; 40 40 long long num; 41 41 42 insn.form = (struct d30v_format *) NULL;42 insn.form = (struct d30v_format *) NULL; 43 43 44 44 info->bytes_per_line = 8; … … 54 54 in1 = bfd_getb32 (buffer); 55 55 56 status = (*info->read_memory_func) (memaddr +4, buffer, 4, info);56 status = (*info->read_memory_func) (memaddr + 4, buffer, 4, info); 57 57 if (status != 0) 58 58 { 59 59 info->bytes_per_line = 8; 60 if (!(result = lookup_opcode (&insn, in1, 0)))61 (*info->fprintf_func) (info->stream, ".long\t0x%x", in1);62 else 63 print_insn (info, memaddr, (long long) in1, &insn, 0, result);64 return 4; 60 if (!(result = lookup_opcode (&insn, in1, 0))) 61 (*info->fprintf_func) (info->stream, ".long\t0x%x", in1); 62 else 63 print_insn (info, memaddr, (long long) in1, &insn, 0, result); 64 return 4; 65 65 } 66 66 in2 = bfd_getb32 (buffer); 67 67 68 68 if (in1 & in2 & FM01) 69 69 { 70 /* LONG instruction */71 if (!(result = lookup_opcode (&insn, in1, 1)))72 { 73 (*info->fprintf_func) (info->stream, ".long\t0x%x,0x%x", in1,in2);70 /* LONG instruction. */ 71 if (!(result = lookup_opcode (&insn, in1, 1))) 72 { 73 (*info->fprintf_func) (info->stream, ".long\t0x%x,0x%x", in1, in2); 74 74 return 8; 75 75 } 76 num = (long long) in1 << 32 | in2;77 print_insn (info, memaddr, num, &insn, 1, result);76 num = (long long) in1 << 32 | in2; 77 print_insn (info, memaddr, num, &insn, 1, result); 78 78 } 79 79 else 80 80 { 81 81 num = in1; 82 if (!(result = lookup_opcode (&insn, in1, 0)))83 (*info->fprintf_func) (info->stream, ".long\t0x%x", in1);84 else 85 print_insn (info, memaddr, num, &insn, 0, result);86 87 switch ( ((in1>>31)<<1) | (in2>>31))82 if (!(result = lookup_opcode (&insn, in1, 0))) 83 (*info->fprintf_func) (info->stream, ".long\t0x%x", in1); 84 else 85 print_insn (info, memaddr, num, &insn, 0, result); 86 87 switch (((in1 >> 31) << 1) | (in2 >> 31)) 88 88 { 89 89 case 0: 90 (*info->fprintf_func) (info->stream, "\t||\t"); 90 (*info->fprintf_func) (info->stream, "\t||\t"); 91 91 break; 92 92 case 1: 93 (*info->fprintf_func) (info->stream, "\t->\t"); 93 (*info->fprintf_func) (info->stream, "\t->\t"); 94 94 break; 95 95 case 2: 96 (*info->fprintf_func) (info->stream, "\t<-\t"); 96 (*info->fprintf_func) (info->stream, "\t<-\t"); 97 97 default: 98 98 break; 99 99 } 100 101 insn.form = (struct d30v_format *) NULL;100 101 insn.form = (struct d30v_format *) NULL; 102 102 num = in2; 103 if (!(result = lookup_opcode(&insn, in2, 0))) 104 (*info->fprintf_func) (info->stream, ".long\t0x%x",in2); 105 else 106 print_insn(info, memaddr, num, &insn, 0, result); 107 103 if (!(result = lookup_opcode (&insn, in2, 0))) 104 (*info->fprintf_func) (info->stream, ".long\t0x%x", in2); 105 else 106 print_insn (info, memaddr, num, &insn, 0, result); 108 107 } 109 108 return 8; 110 109 } 111 110 112 113 /* returns 0 if lookup fails */ 114 /* 1 if found and only one form*/115 /* 2 if found and there are short and long forms */ 111 /* Return 0 if lookup fails, 112 1 if found and only one form, 113 2 if found and there are short and long forms. */ 114 116 115 static int 117 116 lookup_opcode (insn, num, is_long) … … 120 119 int is_long; 121 120 { 122 int i =0, index;121 int i = 0, index; 123 122 struct d30v_format *f; 124 struct d30v_opcode *op = (struct d30v_opcode *) d30v_opcode_table;123 struct d30v_opcode *op = (struct d30v_opcode *) d30v_opcode_table; 125 124 int op1 = (num >> 25) & 0x7; 126 125 int op2 = (num >> 20) & 0x1f; 127 126 int mod = (num >> 18) & 0x3; 128 127 129 /* find the opcode */ 130 do { 131 if ((op->op1 == op1) && (op->op2 == op2)) 132 break; 133 op++; 134 } while (op->name); 128 /* Find the opcode. */ 129 do 130 { 131 if ((op->op1 == op1) && (op->op2 == op2)) 132 break; 133 op++; 134 } 135 while (op->name); 135 136 136 137 if (!op || !op->name) … … 139 140 while (op->op1 == op1 && op->op2 == op2) 140 141 { 141 /* scan through all the formats for the opcode*/142 /* Scan through all the formats for the opcode. */ 142 143 index = op->format[i++]; 143 do 144 { 145 f = (struct d30v_format *) &d30v_format_table[index];144 do 145 { 146 f = (struct d30v_format *) &d30v_format_table[index]; 146 147 while (f->form == index) 147 148 { … … 155 156 if (insn->form) 156 157 break; 157 } while ((index = op->format[i++]) != 0); 158 } 159 while ((index = op->format[i++]) != 0); 158 160 if (insn->form) 159 161 break; 160 162 op++; 161 i =0;163 i = 0; 162 164 } 163 165 if (insn->form == NULL) … … 172 174 } 173 175 174 175 static void 176 print_insn ( info, memaddr, num, insn, is_long, show_ext ) 176 static void 177 print_insn (info, memaddr, num, insn, is_long, show_ext) 177 178 struct disassemble_info *info; 178 179 bfd_vma memaddr; … … 182 183 int show_ext; 183 184 { 184 int val, opnum, need_comma =0;185 int val, opnum, need_comma = 0; 185 186 struct d30v_operand *oper; 186 int i, match, opind =0, need_paren=0, found_control=0;187 188 (*info->fprintf_func) (info->stream, "%s", insn->op->name);189 190 /* check for CMP or CMPU*/187 int i, match, opind = 0, need_paren = 0, found_control = 0; 188 189 (*info->fprintf_func) (info->stream, "%s", insn->op->name); 190 191 /* Check for CMP or CMPU. */ 191 192 if (d30v_operand_table[insn->form->operands[0]].flags & OPERAND_NAME) 192 193 { 193 194 opind++; 194 val = extract_value(num,(struct d30v_operand *)&d30v_operand_table[insn->form->operands[0]],is_long); 195 (*info->fprintf_func) (info->stream, "%s",d30v_cc_names[val]); 196 } 197 198 /* add in ".s" or ".l" */ 195 val = 196 extract_value (num, 197 (struct d30v_operand *) &d30v_operand_table[insn->form->operands[0]], 198 is_long); 199 (*info->fprintf_func) (info->stream, "%s", d30v_cc_names[val]); 200 } 201 202 /* Add in ".s" or ".l". */ 199 203 if (show_ext == 2) 200 204 { … … 206 210 207 211 if (insn->ecc) 208 (*info->fprintf_func) (info->stream, "/%s", d30v_ecc_names[insn->ecc]);212 (*info->fprintf_func) (info->stream, "/%s", d30v_ecc_names[insn->ecc]); 209 213 210 214 (*info->fprintf_func) (info->stream, "\t"); … … 213 217 { 214 218 int bits; 215 oper = (struct d30v_operand *) &d30v_operand_table[opnum];219 oper = (struct d30v_operand *) &d30v_operand_table[opnum]; 216 220 bits = oper->bits; 217 221 if (oper->flags & OPERAND_SHIFT) 218 222 bits += 3; 219 223 220 if (need_comma && oper->flags != OPERAND_PLUS && oper->flags != OPERAND_MINUS) 221 { 222 need_comma=0; 224 if (need_comma 225 && oper->flags != OPERAND_PLUS 226 && oper->flags != OPERAND_MINUS) 227 { 228 need_comma = 0; 223 229 (*info->fprintf_func) (info->stream, ", "); 224 230 } … … 231 237 if (oper->flags == OPERAND_MINUS) 232 238 { 233 (*info->fprintf_func) (info->stream, "-"); 239 (*info->fprintf_func) (info->stream, "-"); 234 240 continue; 235 241 } 236 242 if (oper->flags == OPERAND_PLUS) 237 243 { 238 (*info->fprintf_func) (info->stream, "+"); 244 (*info->fprintf_func) (info->stream, "+"); 239 245 continue; 240 246 } 241 247 if (oper->flags == OPERAND_ATSIGN) 242 248 { 243 (*info->fprintf_func) (info->stream, "@"); 249 (*info->fprintf_func) (info->stream, "@"); 244 250 continue; 245 251 } 246 252 if (oper->flags == OPERAND_ATPAR) 247 253 { 248 (*info->fprintf_func) (info->stream, "@("); 254 (*info->fprintf_func) (info->stream, "@("); 249 255 need_paren = 1; 250 256 continue; … … 254 260 continue; 255 261 256 val = extract_value (num, oper, is_long);257 262 val = extract_value (num, oper, is_long); 263 258 264 if (oper->flags & OPERAND_REG) 259 265 { … … 261 267 if (oper->flags & OPERAND_CONTROL) 262 268 { 263 struct d30v_operand *oper3 = 264 (struct d30v_operand *) &d30v_operand_table[insn->form->operands[2]];265 int id = extract_value (num, oper3, is_long 269 struct d30v_operand *oper3 = 270 (struct d30v_operand *) &d30v_operand_table[insn->form->operands[2]]; 271 int id = extract_value (num, oper3, is_long); 266 272 found_control = 1; 267 switch ( id)273 switch (id) 268 274 { 269 275 case 0: … … 278 284 break; 279 285 default: 280 fprintf (stderr,"illegal id (%d)\n",id);286 fprintf (stderr, "illegal id (%d)\n", id); 281 287 } 282 288 } … … 285 291 else if (oper->flags & OPERAND_FLAG) 286 292 val |= OPERAND_FLAG; 287 for (i =0;i<reg_name_cnt();i++)293 for (i = 0; i < reg_name_cnt (); i++) 288 294 { 289 295 if (val == pre_defined_registers[i].value) … … 291 297 if (pre_defined_registers[i].pname) 292 298 (*info->fprintf_func) 293 (info->stream, "%s", pre_defined_registers[i].pname);299 (info->stream, "%s", pre_defined_registers[i].pname); 294 300 else 295 301 (*info->fprintf_func) 296 (info->stream, "%s", pre_defined_registers[i].name);297 match =1;302 (info->stream, "%s", pre_defined_registers[i].name); 303 match = 1; 298 304 break; 299 305 } 300 306 } 301 if (match ==0)302 { 303 /* this would only get executed if a register was not in the304 register table*/307 if (match == 0) 308 { 309 /* This would only get executed if a register was not in 310 the register table. */ 305 311 (*info->fprintf_func) 306 (info->stream, _("<unknown register %d>"), val & 0x3F); 312 (info->stream, _("<unknown register %d>"), val & 0x3F); 307 313 } 308 314 } 309 315 /* repeati has a relocation, but its first argument is a plain 310 316 immediate. OTOH instructions like djsri have a pc-relative 311 delay target, but a absolute jump target. Therefore, a test317 delay target, but an absolute jump target. Therefore, a test 312 318 of insn->op->reloc_flag is not specific enough; we must test 313 319 if the actual operand we are handling now is pc-relative. */ … … 315 321 { 316 322 int neg = 0; 317 323 318 324 /* IMM6S3 is unsigned. */ 319 325 if (oper->flags & OPERAND_SIGNED || bits == 32) … … 326 332 val = -val; 327 333 else 328 val = -val & ((1 << bits) -1);334 val = -val & ((1 << bits) - 1); 329 335 neg = 1; 330 336 } … … 332 338 if (neg) 333 339 { 334 (*info->fprintf_func) (info->stream, "-%x\t(", val);340 (*info->fprintf_func) (info->stream, "-%x\t(", val); 335 341 (*info->print_address_func) ((memaddr - val) & PC_MASK, info); 336 342 (*info->fprintf_func) (info->stream, ")"); … … 338 344 else 339 345 { 340 (*info->fprintf_func) (info->stream, "%x\t(", val);346 (*info->fprintf_func) (info->stream, "%x\t(", val); 341 347 (*info->print_address_func) ((memaddr + val) & PC_MASK, info); 342 348 (*info->fprintf_func) (info->stream, ")"); … … 360 366 } 361 367 } 362 (*info->fprintf_func) (info->stream, "0x%x", val);363 } 364 /* if there is another operand, then write a comma and space*/368 (*info->fprintf_func) (info->stream, "0x%x", val); 369 } 370 /* If there is another operand, then write a comma and space. */ 365 371 if (insn->form->operands[opind] && !(found_control && opind == 2)) 366 372 need_comma = 1; … … 369 375 (*info->fprintf_func) (info->stream, ")"); 370 376 } 371 372 373 377 374 378 static int … … 384 388 if (is_long) 385 389 { 386 if (oper->bits == 32) 387 { 388 /* piece together 32-bit constant*/390 if (oper->bits == 32) 391 { 392 /* Piece together 32-bit constant. */ 389 393 val = ((num & 0x3FFFF) 390 394 | ((num & 0xFF00000) >> 2) 391 395 | ((num & 0x3F00000000LL) >> 6)); 392 396 } 393 else 394 val = (num >> (32 + shift)) & mask; 397 else 398 val = (num >> (32 + shift)) & mask; 395 399 } 396 400 else -
Property cvs2svn:cvs-rev
changed from
Note:
See TracChangeset
for help on using the changeset viewer.