forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
61 lines
1.6 KiB
61 lines
1.6 KiB
// SPDX-License-Identifier: GPL-2.0 |
|
#include <linux/compiler.h> |
|
|
|
static struct ins_ops *powerpc__associate_instruction_ops(struct arch *arch, const char *name) |
|
{ |
|
int i; |
|
struct ins_ops *ops; |
|
|
|
/* |
|
* - Interested only if instruction starts with 'b'. |
|
* - Few start with 'b', but aren't branch instructions. |
|
*/ |
|
if (name[0] != 'b' || |
|
!strncmp(name, "bcd", 3) || |
|
!strncmp(name, "brinc", 5) || |
|
!strncmp(name, "bper", 4)) |
|
return NULL; |
|
|
|
ops = &jump_ops; |
|
|
|
i = strlen(name) - 1; |
|
if (i < 0) |
|
return NULL; |
|
|
|
/* ignore optional hints at the end of the instructions */ |
|
if (name[i] == '+' || name[i] == '-') |
|
i--; |
|
|
|
if (name[i] == 'l' || (name[i] == 'a' && name[i-1] == 'l')) { |
|
/* |
|
* if the instruction ends up with 'l' or 'la', then |
|
* those are considered 'calls' since they update LR. |
|
* ... except for 'bnl' which is branch if not less than |
|
* and the absolute form of the same. |
|
*/ |
|
if (strcmp(name, "bnl") && strcmp(name, "bnl+") && |
|
strcmp(name, "bnl-") && strcmp(name, "bnla") && |
|
strcmp(name, "bnla+") && strcmp(name, "bnla-")) |
|
ops = &call_ops; |
|
} |
|
if (name[i] == 'r' && name[i-1] == 'l') |
|
/* |
|
* instructions ending with 'lr' are considered to be |
|
* return instructions |
|
*/ |
|
ops = &ret_ops; |
|
|
|
arch__associate_ins_ops(arch, name, ops); |
|
return ops; |
|
} |
|
|
|
static int powerpc__annotate_init(struct arch *arch, char *cpuid __maybe_unused) |
|
{ |
|
if (!arch->initialized) { |
|
arch->initialized = true; |
|
arch->associate_instruction_ops = powerpc__associate_instruction_ops; |
|
arch->objdump.comment_char = '#'; |
|
} |
|
|
|
return 0; |
|
}
|
|
|