123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- // SPDX-License-Identifier: GPL-2.0
- static int is_branch_cond(const char *cond)
- {
- if (cond[0] == '\0')
- return 1;
- if (cond[0] == 'a' && cond[1] == '\0')
- return 1;
- if (cond[0] == 'c' &&
- (cond[1] == 'c' || cond[1] == 's') &&
- cond[2] == '\0')
- return 1;
- if (cond[0] == 'e' &&
- (cond[1] == '\0' ||
- (cond[1] == 'q' && cond[2] == '\0')))
- return 1;
- if (cond[0] == 'g' &&
- (cond[1] == '\0' ||
- (cond[1] == 't' && cond[2] == '\0') ||
- (cond[1] == 'e' && cond[2] == '\0') ||
- (cond[1] == 'e' && cond[2] == 'u' && cond[3] == '\0')))
- return 1;
- if (cond[0] == 'l' &&
- (cond[1] == '\0' ||
- (cond[1] == 't' && cond[2] == '\0') ||
- (cond[1] == 'u' && cond[2] == '\0') ||
- (cond[1] == 'e' && cond[2] == '\0') ||
- (cond[1] == 'e' && cond[2] == 'u' && cond[3] == '\0')))
- return 1;
- if (cond[0] == 'n' &&
- (cond[1] == '\0' ||
- (cond[1] == 'e' && cond[2] == '\0') ||
- (cond[1] == 'z' && cond[2] == '\0') ||
- (cond[1] == 'e' && cond[2] == 'g' && cond[3] == '\0')))
- return 1;
- if (cond[0] == 'b' &&
- cond[1] == 'p' &&
- cond[2] == 'o' &&
- cond[3] == 's' &&
- cond[4] == '\0')
- return 1;
- if (cond[0] == 'v' &&
- (cond[1] == 'c' || cond[1] == 's') &&
- cond[2] == '\0')
- return 1;
- if (cond[0] == 'b' &&
- cond[1] == 'z' &&
- cond[2] == '\0')
- return 1;
- return 0;
- }
- static int is_branch_reg_cond(const char *cond)
- {
- if ((cond[0] == 'n' || cond[0] == 'l') &&
- cond[1] == 'z' &&
- cond[2] == '\0')
- return 1;
- if (cond[0] == 'z' &&
- cond[1] == '\0')
- return 1;
- if ((cond[0] == 'g' || cond[0] == 'l') &&
- cond[1] == 'e' &&
- cond[2] == 'z' &&
- cond[3] == '\0')
- return 1;
- if (cond[0] == 'g' &&
- cond[1] == 'z' &&
- cond[2] == '\0')
- return 1;
- return 0;
- }
- static int is_branch_float_cond(const char *cond)
- {
- if (cond[0] == '\0')
- return 1;
- if ((cond[0] == 'a' || cond[0] == 'e' ||
- cond[0] == 'z' || cond[0] == 'g' ||
- cond[0] == 'l' || cond[0] == 'n' ||
- cond[0] == 'o' || cond[0] == 'u') &&
- cond[1] == '\0')
- return 1;
- if (((cond[0] == 'g' && cond[1] == 'e') ||
- (cond[0] == 'l' && (cond[1] == 'e' ||
- cond[1] == 'g')) ||
- (cond[0] == 'n' && (cond[1] == 'e' ||
- cond[1] == 'z')) ||
- (cond[0] == 'u' && (cond[1] == 'e' ||
- cond[1] == 'g' ||
- cond[1] == 'l'))) &&
- cond[2] == '\0')
- return 1;
- if (cond[0] == 'u' &&
- (cond[1] == 'g' || cond[1] == 'l') &&
- cond[2] == 'e' &&
- cond[3] == '\0')
- return 1;
- return 0;
- }
- static struct ins_ops *sparc__associate_instruction_ops(struct arch *arch, const char *name)
- {
- struct ins_ops *ops = NULL;
- if (!strcmp(name, "call") ||
- !strcmp(name, "jmp") ||
- !strcmp(name, "jmpl")) {
- ops = &call_ops;
- } else if (!strcmp(name, "ret") ||
- !strcmp(name, "retl") ||
- !strcmp(name, "return")) {
- ops = &ret_ops;
- } else if (!strcmp(name, "mov")) {
- ops = &mov_ops;
- } else {
- if (name[0] == 'c' &&
- (name[1] == 'w' || name[1] == 'x'))
- name += 2;
- if (name[0] == 'b') {
- const char *cond = name + 1;
- if (cond[0] == 'r') {
- if (is_branch_reg_cond(cond + 1))
- ops = &jump_ops;
- } else if (is_branch_cond(cond)) {
- ops = &jump_ops;
- }
- } else if (name[0] == 'f' && name[1] == 'b') {
- if (is_branch_float_cond(name + 2))
- ops = &jump_ops;
- }
- }
- if (ops)
- arch__associate_ins_ops(arch, name, ops);
- return ops;
- }
- static int sparc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
- {
- if (!arch->initialized) {
- arch->initialized = true;
- arch->associate_instruction_ops = sparc__associate_instruction_ops;
- arch->objdump.comment_char = '#';
- }
- return 0;
- }
|