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