1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/compiler.h> 3 4 static struct ins_ops *powerpc__associate_instruction_ops(struct arch *arch, const char *name) 5 { 6 int i; 7 struct ins_ops *ops; 8 9 /* 10 * - Interested only if instruction starts with 'b'. 11 * - Few start with 'b', but aren't branch instructions. 12 */ 13 if (name[0] != 'b' || 14 !strncmp(name, "bcd", 3) || 15 !strncmp(name, "brinc", 5) || 16 !strncmp(name, "bper", 4)) 17 return NULL; 18 19 ops = &jump_ops; 20 21 i = strlen(name) - 1; 22 if (i < 0) 23 return NULL; 24 25 /* ignore optional hints at the end of the instructions */ 26 if (name[i] == '+' || name[i] == '-') 27 i--; 28 29 if (name[i] == 'l' || (name[i] == 'a' && name[i-1] == 'l')) { 30 /* 31 * if the instruction ends up with 'l' or 'la', then 32 * those are considered 'calls' since they update LR. 33 * ... except for 'bnl' which is branch if not less than 34 * and the absolute form of the same. 35 */ 36 if (strcmp(name, "bnl") && strcmp(name, "bnl+") && 37 strcmp(name, "bnl-") && strcmp(name, "bnla") && 38 strcmp(name, "bnla+") && strcmp(name, "bnla-")) 39 ops = &call_ops; 40 } 41 if (name[i] == 'r' && name[i-1] == 'l') 42 /* 43 * instructions ending with 'lr' are considered to be 44 * return instructions 45 */ 46 ops = &ret_ops; 47 48 arch__associate_ins_ops(arch, name, ops); 49 return ops; 50 } 51 52 static int powerpc__annotate_init(struct arch *arch, char *cpuid __maybe_unused) 53 { 54 if (!arch->initialized) { 55 arch->initialized = true; 56 arch->associate_instruction_ops = powerpc__associate_instruction_ops; 57 arch->objdump.comment_char = '#'; 58 } 59 60 return 0; 61 } 62