1
2
3#include <common.h>
4#include <asm/ptrace.h>
5
6#include <linux/ctype.h>
7#include <bedbug/bedbug.h>
8#include <bedbug/ppc.h>
9#include <bedbug/regs.h>
10#include <bedbug/tables.h>
11
12#define Elf32_Word unsigned long
13
14
15
16
17
18
19
20
21#ifdef USE_SOURCE_CODE
22extern int line_info_from_addr __P ((Elf32_Word, char *, char *, int *));
23extern struct symreflist *symByAddr;
24extern char *symbol_name_from_addr __P ((Elf32_Word, int, int *));
25#endif
26
27int print_operands __P ((struct ppc_ctx *));
28int get_operand_value __P ((struct opcode *, unsigned long,
29 enum OP_FIELD, unsigned long *));
30struct opcode *find_opcode __P ((unsigned long));
31struct opcode *find_opcode_by_name __P ((char *));
32char *spr_name __P ((int));
33int spr_value __P ((char *));
34char *tbr_name __P ((int));
35int tbr_value __P ((char *));
36int parse_operand __P ((unsigned long, struct opcode *,
37 struct operand *, char *, int *));
38int get_word __P ((char **, char *));
39long read_number __P ((char *));
40int downstring __P ((char *));
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80int disppc (unsigned char *memaddr, unsigned char *virtual, int num_instr,
81 int (*pfunc) (const char *), unsigned long flags)
82{
83 int i;
84 struct ppc_ctx ctx;
85
86#ifdef USE_SOURCE_CODE
87 int line_no = 0;
88 int last_line_no = 0;
89 char funcname[128] = { 0 };
90 char filename[256] = { 0 };
91 char last_funcname[128] = { 0 };
92 int symoffset;
93 char *symname;
94 char *cursym = (char *) 0;
95#endif
96
97
98 ctx.flags = flags;
99 ctx.virtual = virtual;
100
101
102
103 if (ctx.flags & F_RADOCTAL) {
104
105 strcpy (ctx.radix_fmt, "O%o");
106 } else if (ctx.flags & F_RADUDECIMAL) {
107
108 strcpy (ctx.radix_fmt, "%u");
109 } else if (ctx.flags & F_RADSDECIMAL) {
110
111 strcpy (ctx.radix_fmt, "%d");
112 } else {
113
114 strcpy (ctx.radix_fmt, "0x%x");
115 }
116
117 if (ctx.virtual == 0) {
118 ctx.virtual = memaddr;
119 }
120#ifdef USE_SOURCE_CODE
121 if (ctx.flags & F_SYMBOL) {
122 if (symByAddr == 0)
123 ctx.flags &= ~F_SYMBOL;
124 else {
125 cursym = (char *) 0;
126 symoffset = 0;
127 }
128 }
129#endif
130
131
132
133
134
135
136
137
138 for (i = 0; i < num_instr; ++i, memaddr += 4, ctx.virtual += 4) {
139#ifdef USE_SOURCE_CODE
140 if (ctx.flags & F_LINENO) {
141 if ((line_info_from_addr ((Elf32_Word) ctx.virtual,
142 filename, funcname, &line_no) == true) &&
143 ((line_no != last_line_no) ||
144 (strcmp (last_funcname, funcname) != 0))) {
145 print_source_line (filename, funcname, line_no, pfunc);
146 }
147 last_line_no = line_no;
148 strcpy (last_funcname, funcname);
149 }
150#endif
151
152 sprintf (ctx.data, "%08lx: ", (unsigned long) ctx.virtual);
153 ctx.datalen = 10;
154
155#ifdef USE_SOURCE_CODE
156 if (ctx.flags & F_SYMBOL) {
157 if ((symname =
158 symbol_name_from_addr((Elf32_Word) ctx.virtual,
159 true, 0)) != 0) {
160 cursym = symname;
161 symoffset = 0;
162 } else {
163 if ((cursym == 0) &&
164 ((symname =
165 symbol_name_from_addr((Elf32_Word) ctx.virtual,
166 false, &symoffset)) != 0)) {
167 cursym = symname;
168 } else {
169 symoffset += 4;
170 }
171 }
172
173 if (cursym != 0) {
174 sprintf (&ctx.data[ctx.datalen], "<%s+", cursym);
175 ctx.datalen = strlen (ctx.data);
176 sprintf (&ctx.data[ctx.datalen], ctx.radix_fmt, symoffset);
177 strcat (ctx.data, ">");
178 ctx.datalen = strlen (ctx.data);
179 }
180 }
181#endif
182
183 ctx.instr = INSTRUCTION (memaddr);
184
185 if (ctx.flags & F_INSTR) {
186
187
188 sprintf (&ctx.data[ctx.datalen],
189 " %02lx %02lx %02lx %02lx ",
190 ((ctx.instr >> 24) & 0xff),
191 ((ctx.instr >> 16) & 0xff), ((ctx.instr >> 8) & 0xff),
192 (ctx.instr & 0xff));
193 ctx.datalen += 18;
194 } else {
195 strcat (ctx.data, " ");
196 ctx.datalen += 3;
197 }
198
199 if ((ctx.op = find_opcode (ctx.instr)) == 0) {
200
201 sprintf (&ctx.data[ctx.datalen], " .long 0x%08lx",
202 ctx.instr);
203 ctx.datalen += 24;
204 (*pfunc) (ctx.data);
205 continue;
206 }
207
208 if (((ctx.flags & F_SIMPLE) == 0) ||
209 (ctx.op->hfunc == 0) ||
210 ((*ctx.op->hfunc) (&ctx) == false)) {
211 sprintf (&ctx.data[ctx.datalen], "%-7s ", ctx.op->name);
212 ctx.datalen += 8;
213 print_operands (&ctx);
214 }
215
216 (*pfunc) (ctx.data);
217 }
218
219 return true;
220}
221
222
223
224
225
226
227
228
229
230
231
232
233int print_operands (struct ppc_ctx *ctx)
234{
235 int open_parens = 0;
236 int field;
237 unsigned long operand;
238 struct operand *opr;
239
240#ifdef USE_SOURCE_CODE
241 char *symname;
242 int offset;
243#endif
244
245
246
247 for (field = 0; ctx->op->fields[field] != 0; ++field) {
248 if (ctx->op->fields[field] > n_operands) {
249 continue;
250 }
251
252 opr = &operands[ctx->op->fields[field] - 1];
253
254 if (opr->hint & OH_SILENT) {
255 continue;
256 }
257
258 if ((field > 0) && !open_parens) {
259 strcat (ctx->data, ",");
260 ctx->datalen++;
261 }
262
263 operand = (ctx->instr >> opr->shift) & ((1 << opr->bits) - 1);
264
265 if (opr->hint & OH_ADDR) {
266 if ((operand & (1 << (opr->bits - 1))) != 0) {
267 operand = operand - (1 << opr->bits);
268 }
269
270 if (ctx->op->hint & H_RELATIVE)
271 operand = (operand << 2) + (unsigned long) ctx->virtual;
272 else
273 operand = (operand << 2);
274
275
276 sprintf (&ctx->data[ctx->datalen], "0x%lx", operand);
277 ctx->datalen = strlen (ctx->data);
278
279#ifdef USE_SOURCE_CODE
280 if ((ctx->flags & F_SYMBOL) &&
281 ((symname =
282 symbol_name_from_addr (operand, 0, &offset)) != 0)) {
283 sprintf (&ctx->data[ctx->datalen], " <%s", symname);
284 if (offset != 0) {
285 strcat (ctx->data, "+");
286 ctx->datalen = strlen (ctx->data);
287 sprintf (&ctx->data[ctx->datalen], ctx->radix_fmt,
288 offset);
289 }
290 strcat (ctx->data, ">");
291 }
292#endif
293 }
294
295 else if (opr->hint & OH_REG) {
296 if ((operand == 0) &&
297 (opr->field == O_rA) && (ctx->op->hint & H_RA0_IS_0)) {
298 strcat (ctx->data, "0");
299 } else {
300 sprintf (&ctx->data[ctx->datalen], "r%d", (short) operand);
301 }
302
303 if (open_parens) {
304 strcat (ctx->data, ")");
305 open_parens--;
306 }
307 }
308
309 else if (opr->hint & OH_SPR) {
310 strcat (ctx->data, spr_name (operand));
311 }
312
313 else if (opr->hint & OH_TBR) {
314 strcat (ctx->data, tbr_name (operand));
315 }
316
317 else if (opr->hint & OH_LITERAL) {
318 switch (opr->field) {
319 case O_cr2:
320 strcat (ctx->data, "cr2");
321 ctx->datalen += 3;
322 break;
323
324 default:
325 break;
326 }
327 }
328
329 else {
330 sprintf (&ctx->data[ctx->datalen], ctx->radix_fmt,
331 (unsigned short) operand);
332
333 if (open_parens) {
334 strcat (ctx->data, ")");
335 open_parens--;
336 }
337
338 else if (opr->hint & OH_OFFSET) {
339 strcat (ctx->data, "(");
340 open_parens++;
341 }
342 }
343
344 ctx->datalen = strlen (ctx->data);
345 }
346
347 return 0;
348}
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375int get_operand_value (struct opcode *op, unsigned long instr,
376 enum OP_FIELD field, unsigned long *value)
377{
378 int i;
379 struct operand *opr;
380
381
382
383 if (field > n_operands) {
384 return false;
385 }
386
387
388 for (i = 0; op->fields[i] != 0; ++i) {
389 if (op->fields[i] != field) {
390 continue;
391 }
392
393 opr = &operands[op->fields[i] - 1];
394
395 if (value) {
396 *value = (instr >> opr->shift) & ((1 << opr->bits) - 1);
397 }
398 return true;
399 }
400
401 return false;
402}
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419struct opcode *find_opcode (unsigned long instr)
420{
421 struct opcode *ptr;
422 int top = 0;
423 int bottom = n_opcodes - 1;
424 int idx;
425
426
427
428 while (top <= bottom) {
429 idx = (top + bottom) >> 1;
430 ptr = &opcodes[idx];
431
432 if ((instr & ptr->mask) < ptr->opcode) {
433 bottom = idx - 1;
434 } else if ((instr & ptr->mask) > ptr->opcode) {
435 top = idx + 1;
436 } else {
437 return ptr;
438 }
439 }
440
441 return (struct opcode *) 0;
442}
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460struct opcode *find_opcode_by_name (char *name)
461{
462 int idx;
463
464
465
466 downstring (name);
467
468 for (idx = 0; idx < n_opcodes; ++idx) {
469 if (!strcmp (name, opcodes[idx].name))
470 return &opcodes[idx];
471 }
472
473 return (struct opcode *) 0;
474}
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492char *spr_name (int value)
493{
494 unsigned short spr;
495 static char other[10];
496 int i;
497
498
499
500
501
502
503 spr = ((value >> 5) & 0x1f) | ((value & 0x1f) << 5);
504
505 for (i = 0; i < n_sprs; ++i) {
506 if (spr == spr_map[i].spr_val)
507 return spr_map[i].spr_name;
508 }
509
510 sprintf (other, "%d", spr);
511 return other;
512}
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528int spr_value (char *name)
529{
530 struct spr_info *sprp;
531 int spr;
532 int i;
533
534
535
536 if (!name || !*name)
537 return 0;
538
539 if (isdigit ((int) name[0])) {
540 i = htonl (read_number (name));
541 spr = ((i >> 5) & 0x1f) | ((i & 0x1f) << 5);
542 return spr;
543 }
544
545 downstring (name);
546
547 for (i = 0; i < n_sprs; ++i) {
548 sprp = &spr_map[i];
549
550 if (strcmp (name, sprp->spr_name) == 0) {
551
552
553 i = htonl (sprp->spr_val);
554 spr = ((i >> 5) & 0x1f) | ((i & 0x1f) << 5);
555
556 return spr;
557 }
558 }
559
560 return 0;
561}
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579char *tbr_name (int value)
580{
581 unsigned short tbr;
582
583
584
585
586
587
588 tbr = ((value >> 5) & 0x1f) | ((value & 0x1f) << 5);
589
590 if (tbr == 268)
591 return "TBL";
592
593 else if (tbr == 269)
594 return "TBU";
595
596
597 return "???";
598}
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613int tbr_value (char *name)
614{
615 int tbr;
616 int val;
617
618
619
620 if (!name || !*name)
621 return 0;
622
623 downstring (name);
624
625 if (isdigit ((int) name[0])) {
626 val = read_number (name);
627
628 if (val != 268 && val != 269)
629 return 0;
630 } else if (strcmp (name, "tbl") == 0)
631 val = 268;
632 else if (strcmp (name, "tbu") == 0)
633 val = 269;
634 else
635 return 0;
636
637
638
639
640 val = htonl (val);
641 tbr = ((val >> 5) & 0x1f) | ((val & 0x1f) << 5);
642 return tbr;
643}
644
645
646
647
648
649
650
651
652
653
654
655
656
657int handle_bc (struct ppc_ctx *ctx)
658{
659 unsigned long bo;
660 unsigned long bi;
661 static struct opcode blt = { B_OPCODE (16, 0, 0), B_MASK, {O_BD, 0},
662 0, "blt", H_RELATIVE
663 };
664 static struct opcode bne =
665 { B_OPCODE (16, 0, 0), B_MASK, {O_cr2, O_BD, 0},
666 0, "bne", H_RELATIVE
667 };
668 static struct opcode bdnz = { B_OPCODE (16, 0, 0), B_MASK, {O_BD, 0},
669 0, "bdnz", H_RELATIVE
670 };
671
672
673
674 if (get_operand_value(ctx->op, ctx->instr, O_BO, &bo) == false)
675 return false;
676
677 if (get_operand_value(ctx->op, ctx->instr, O_BI, &bi) == false)
678 return false;
679
680 if ((bo == 12) && (bi == 0)) {
681 ctx->op = &blt;
682 sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name);
683 ctx->datalen += 8;
684 print_operands (ctx);
685 return true;
686 } else if ((bo == 4) && (bi == 10)) {
687 ctx->op = =⃥
688 sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name);
689 ctx->datalen += 8;
690 print_operands (ctx);
691 return true;
692 } else if ((bo == 16) && (bi == 0)) {
693 ctx->op = &bdnz;
694 sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name);
695 ctx->datalen += 8;
696 print_operands (ctx);
697 return true;
698 }
699
700 return false;
701}
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728int print_source_line (char *filename, char *funcname,
729 int line_no, int (*pfunc) (const char *))
730{
731 char out_buf[256];
732
733
734
735 (*pfunc) ("");
736 sprintf (out_buf, "%s %s(): line %d", filename, funcname, line_no);
737 (*pfunc) (out_buf);
738
739 return true;
740}
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755unsigned long asmppc (unsigned long memaddr, char *asm_buf, int *err)
756{
757 struct opcode *opc;
758 struct operand *oper[MAX_OPERANDS];
759 unsigned long instr;
760 unsigned long param;
761 char *ptr = asm_buf;
762 char scratch[20];
763 int i;
764 int w_operands = 0;
765 int n_operands = 0;
766 int asm_debug = 0;
767
768
769
770 if (err)
771 *err = 0;
772
773 if (get_word (&ptr, scratch) == 0)
774 return 0;
775
776
777 if ((opc = find_opcode_by_name (scratch)) == (struct opcode *) 0) {
778 if (err)
779 *err = E_ASM_BAD_OPCODE;
780 return 0;
781 }
782
783 if (asm_debug) {
784 printf ("asmppc: Opcode = \"%s\"\n", opc->name);
785 }
786
787 for (i = 0; i < 8; ++i) {
788 if (opc->fields[i] == 0)
789 break;
790 ++w_operands;
791 }
792
793 if (asm_debug) {
794 printf ("asmppc: Expecting %d operands\n", w_operands);
795 }
796
797 instr = opc->opcode;
798
799
800 while (n_operands < w_operands) {
801
802 oper[n_operands] = &operands[opc->fields[n_operands] - 1];
803
804 if (oper[n_operands]->hint & OH_SILENT) {
805
806
807 if (asm_debug) {
808 printf ("asmppc: Operand %d \"%s\" SILENT\n", n_operands,
809 oper[n_operands]->name);
810 }
811
812 ++n_operands;
813 continue;
814 }
815
816 if (get_word (&ptr, scratch) == 0)
817 break;
818
819 if (asm_debug) {
820 printf ("asmppc: Operand %d \"%s\" : \"%s\"\n", n_operands,
821 oper[n_operands]->name, scratch);
822 }
823
824 if ((param = parse_operand (memaddr, opc, oper[n_operands],
825 scratch, err)) == -1)
826 return 0;
827
828 instr |= param;
829 ++n_operands;
830 }
831
832 if (n_operands < w_operands) {
833 if (err)
834 *err = E_ASM_NUM_OPERANDS;
835 return 0;
836 }
837
838 if (asm_debug) {
839 printf ("asmppc: Instruction = 0x%08lx\n", instr);
840 }
841
842 return instr;
843}
844
845
846
847
848
849
850
851
852
853
854
855
856int parse_operand (unsigned long memaddr, struct opcode *opc,
857 struct operand *oper, char *txt, int *err)
858{
859 long data;
860 long mask;
861 int is_neg = 0;
862
863
864
865 mask = (1 << oper->bits) - 1;
866
867 if (oper->hint & OH_ADDR) {
868 data = read_number (txt);
869
870 if (opc->hint & H_RELATIVE)
871 data = data - memaddr;
872
873 if (data < 0)
874 is_neg = 1;
875
876 data >>= 2;
877 data &= (mask >> 1);
878
879 if (is_neg)
880 data |= 1 << (oper->bits - 1);
881 }
882
883 else if (oper->hint & OH_REG) {
884 if (txt[0] == 'r' || txt[0] == 'R')
885 txt++;
886 else if (txt[0] == '%' && (txt[1] == 'r' || txt[1] == 'R'))
887 txt += 2;
888
889 data = read_number (txt);
890 if (data > 31) {
891 if (err)
892 *err = E_ASM_BAD_REGISTER;
893 return -1;
894 }
895
896 data = htonl (data);
897 }
898
899 else if (oper->hint & OH_SPR) {
900 if ((data = spr_value (txt)) == 0) {
901 if (err)
902 *err = E_ASM_BAD_SPR;
903 return -1;
904 }
905 }
906
907 else if (oper->hint & OH_TBR) {
908 if ((data = tbr_value (txt)) == 0) {
909 if (err)
910 *err = E_ASM_BAD_TBR;
911 return -1;
912 }
913 }
914
915 else {
916 data = htonl (read_number (txt));
917 }
918
919 return (data & mask) << oper->shift;
920}
921
922
923char *asm_error_str (int err)
924{
925 switch (err) {
926 case E_ASM_BAD_OPCODE:
927 return "Bad opcode";
928 case E_ASM_NUM_OPERANDS:
929 return "Bad number of operands";
930 case E_ASM_BAD_REGISTER:
931 return "Bad register number";
932 case E_ASM_BAD_SPR:
933 return "Bad SPR name or number";
934 case E_ASM_BAD_TBR:
935 return "Bad TBR name or number";
936 }
937
938 return "";
939}
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955int get_word (char **src, char *dest)
956{
957 char *ptr = *src;
958 int nchars = 0;
959
960
961
962
963 while (*ptr && isblank (*ptr))
964 ptr++;
965
966 if (*ptr == 0) {
967 *src = ptr;
968 return 0;
969 }
970
971
972 while (*ptr && !isblank (*ptr) && (*ptr != ','))
973 dest[nchars++] = *ptr++;
974 ptr = (*ptr == ',') ? ptr + 1 : ptr;
975 dest[nchars] = 0;
976
977 *src = ptr;
978 return nchars;
979}
980
981
982
983
984
985
986
987
988
989
990
991
992long read_number (char *txt)
993{
994 long val;
995 int is_neg = 0;
996
997
998
999 if (txt == 0 || *txt == 0)
1000 return 0;
1001
1002 if (*txt == '-') {
1003 is_neg = 1;
1004 ++txt;
1005 }
1006
1007 if (txt[0] == '0' && (txt[1] == 'x' || txt[1] == 'X'))
1008 val = hextoul(&txt[2], NULL);
1009 else
1010 val = dectoul(txt, NULL);
1011
1012 if (is_neg)
1013 val = -val;
1014
1015 return val;
1016}
1017
1018
1019int downstring (char *s)
1020{
1021 if (!s || !*s)
1022 return 0;
1023
1024 while (*s) {
1025 if (isupper (*s))
1026 *s = tolower (*s);
1027 s++;
1028 }
1029
1030 return 0;
1031}
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055int find_next_address (unsigned char *nextaddr, int step_over,
1056 struct pt_regs *regs)
1057{
1058 unsigned long pc;
1059 unsigned long ctr;
1060 unsigned long cr;
1061 unsigned long lr;
1062 unsigned long instr;
1063 unsigned long next;
1064 unsigned long step;
1065 unsigned long addr = 0;
1066 unsigned long aa = 0;
1067 unsigned long lk = 0;
1068 unsigned long bo = 0;
1069 unsigned long bi = 0;
1070 struct opcode *op = 0;
1071 int ctr_ok = 0;
1072 int cond_ok = 0;
1073 int conditional = 0;
1074 int branch = 0;
1075
1076
1077
1078 if (nextaddr == 0 || regs == 0) {
1079 printf ("find_next_address: bad args");
1080 return false;
1081 }
1082
1083 pc = regs->nip & 0xfffffffc;
1084 instr = INSTRUCTION (pc);
1085
1086 if ((op = find_opcode (instr)) == (struct opcode *) 0) {
1087 printf ("find_next_address: can't parse opcode 0x%lx", instr);
1088 return false;
1089 }
1090
1091 ctr = regs->ctr;
1092 cr = regs->ccr;
1093 lr = regs->link;
1094
1095 switch (op->opcode) {
1096 case B_OPCODE (16, 0, 0):
1097 case B_OPCODE (16, 0, 1):
1098 case B_OPCODE (16, 1, 0):
1099 case B_OPCODE (16, 1, 1):
1100 if (!get_operand_value (op, instr, O_BD, &addr) ||
1101 !get_operand_value (op, instr, O_BO, &bo) ||
1102 !get_operand_value (op, instr, O_BI, &bi) ||
1103 !get_operand_value (op, instr, O_AA, &aa) ||
1104 !get_operand_value (op, instr, O_LK, &lk))
1105 return false;
1106
1107 if ((addr & (1 << 13)) != 0)
1108 addr = addr - (1 << 14);
1109 addr <<= 2;
1110 conditional = 1;
1111 branch = 1;
1112 break;
1113
1114 case I_OPCODE (18, 0, 0):
1115 case I_OPCODE (18, 0, 1):
1116 case I_OPCODE (18, 1, 0):
1117 case I_OPCODE (18, 1, 1):
1118 if (!get_operand_value (op, instr, O_LI, &addr) ||
1119 !get_operand_value (op, instr, O_AA, &aa) ||
1120 !get_operand_value (op, instr, O_LK, &lk))
1121 return false;
1122
1123 if ((addr & (1 << 23)) != 0)
1124 addr = addr - (1 << 24);
1125 addr <<= 2;
1126 conditional = 0;
1127 branch = 1;
1128 break;
1129
1130 case XL_OPCODE (19, 528, 0):
1131 case XL_OPCODE (19, 528, 1):
1132 if (!get_operand_value (op, instr, O_BO, &bo) ||
1133 !get_operand_value (op, instr, O_BI, &bi) ||
1134 !get_operand_value (op, instr, O_LK, &lk))
1135 return false;
1136
1137 addr = ctr;
1138 aa = 1;
1139 conditional = 1;
1140 branch = 1;
1141 break;
1142
1143 case XL_OPCODE (19, 16, 0):
1144 case XL_OPCODE (19, 16, 1):
1145 if (!get_operand_value (op, instr, O_BO, &bo) ||
1146 !get_operand_value (op, instr, O_BI, &bi) ||
1147 !get_operand_value (op, instr, O_LK, &lk))
1148 return false;
1149
1150 addr = lr;
1151 aa = 1;
1152 conditional = 1;
1153 branch = 1;
1154 break;
1155
1156 default:
1157 conditional = 0;
1158 branch = 0;
1159 break;
1160 }
1161
1162 if (conditional) {
1163 switch ((bo & 0x1e) >> 1) {
1164 case 0:
1165 if (--ctr != 0)
1166 ctr_ok = 1;
1167
1168 cond_ok = !(cr & (1 << (31 - bi)));
1169 break;
1170
1171 case 1:
1172 if (--ctr == 0)
1173 ctr_ok = 1;
1174
1175 cond_ok = !(cr & (1 << (31 - bi)));
1176 break;
1177
1178 case 2:
1179 ctr_ok = 1;
1180 cond_ok = !(cr & (1 << (31 - bi)));
1181 break;
1182
1183 case 4:
1184 if (--ctr != 0)
1185 ctr_ok = 1;
1186
1187 cond_ok = cr & (1 << (31 - bi));
1188 break;
1189
1190 case 5:
1191 if (--ctr == 0)
1192 ctr_ok = 1;
1193
1194 cond_ok = cr & (1 << (31 - bi));
1195 break;
1196
1197 case 6:
1198 ctr_ok = 1;
1199 cond_ok = cr & (1 << (31 - bi));
1200 break;
1201
1202 case 8:
1203 if (--ctr != 0)
1204 ctr_ok = cond_ok = 1;
1205 break;
1206
1207 case 9:
1208 if (--ctr == 0)
1209 ctr_ok = cond_ok = 1;
1210 break;
1211
1212 case 10:
1213 ctr_ok = cond_ok = 1;
1214 break;
1215 }
1216 }
1217
1218 if (branch && (!conditional || (ctr_ok && cond_ok))) {
1219 if (aa)
1220 step = addr;
1221 else
1222 step = addr + pc;
1223
1224 if (lk)
1225 next = pc + 4;
1226 else
1227 next = step;
1228 } else {
1229 step = next = pc + 4;
1230 }
1231
1232 if (step_over == true)
1233 *(unsigned long *) nextaddr = next;
1234 else
1235 *(unsigned long *) nextaddr = step;
1236
1237 return true;
1238}
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255