Path: blob/master/tools/perf/arch/sparc/annotate/instructions.c
26305 views
// SPDX-License-Identifier: GPL-2.012static int is_branch_cond(const char *cond)3{4if (cond[0] == '\0')5return 1;67if (cond[0] == 'a' && cond[1] == '\0')8return 1;910if (cond[0] == 'c' &&11(cond[1] == 'c' || cond[1] == 's') &&12cond[2] == '\0')13return 1;1415if (cond[0] == 'e' &&16(cond[1] == '\0' ||17(cond[1] == 'q' && cond[2] == '\0')))18return 1;1920if (cond[0] == 'g' &&21(cond[1] == '\0' ||22(cond[1] == 't' && cond[2] == '\0') ||23(cond[1] == 'e' && cond[2] == '\0') ||24(cond[1] == 'e' && cond[2] == 'u' && cond[3] == '\0')))25return 1;2627if (cond[0] == 'l' &&28(cond[1] == '\0' ||29(cond[1] == 't' && cond[2] == '\0') ||30(cond[1] == 'u' && cond[2] == '\0') ||31(cond[1] == 'e' && cond[2] == '\0') ||32(cond[1] == 'e' && cond[2] == 'u' && cond[3] == '\0')))33return 1;3435if (cond[0] == 'n' &&36(cond[1] == '\0' ||37(cond[1] == 'e' && cond[2] == '\0') ||38(cond[1] == 'z' && cond[2] == '\0') ||39(cond[1] == 'e' && cond[2] == 'g' && cond[3] == '\0')))40return 1;4142if (cond[0] == 'b' &&43cond[1] == 'p' &&44cond[2] == 'o' &&45cond[3] == 's' &&46cond[4] == '\0')47return 1;4849if (cond[0] == 'v' &&50(cond[1] == 'c' || cond[1] == 's') &&51cond[2] == '\0')52return 1;5354if (cond[0] == 'b' &&55cond[1] == 'z' &&56cond[2] == '\0')57return 1;5859return 0;60}6162static int is_branch_reg_cond(const char *cond)63{64if ((cond[0] == 'n' || cond[0] == 'l') &&65cond[1] == 'z' &&66cond[2] == '\0')67return 1;6869if (cond[0] == 'z' &&70cond[1] == '\0')71return 1;7273if ((cond[0] == 'g' || cond[0] == 'l') &&74cond[1] == 'e' &&75cond[2] == 'z' &&76cond[3] == '\0')77return 1;7879if (cond[0] == 'g' &&80cond[1] == 'z' &&81cond[2] == '\0')82return 1;8384return 0;85}8687static int is_branch_float_cond(const char *cond)88{89if (cond[0] == '\0')90return 1;9192if ((cond[0] == 'a' || cond[0] == 'e' ||93cond[0] == 'z' || cond[0] == 'g' ||94cond[0] == 'l' || cond[0] == 'n' ||95cond[0] == 'o' || cond[0] == 'u') &&96cond[1] == '\0')97return 1;9899if (((cond[0] == 'g' && cond[1] == 'e') ||100(cond[0] == 'l' && (cond[1] == 'e' ||101cond[1] == 'g')) ||102(cond[0] == 'n' && (cond[1] == 'e' ||103cond[1] == 'z')) ||104(cond[0] == 'u' && (cond[1] == 'e' ||105cond[1] == 'g' ||106cond[1] == 'l'))) &&107cond[2] == '\0')108return 1;109110if (cond[0] == 'u' &&111(cond[1] == 'g' || cond[1] == 'l') &&112cond[2] == 'e' &&113cond[3] == '\0')114return 1;115116return 0;117}118119static struct ins_ops *sparc__associate_instruction_ops(struct arch *arch, const char *name)120{121struct ins_ops *ops = NULL;122123if (!strcmp(name, "call") ||124!strcmp(name, "jmp") ||125!strcmp(name, "jmpl")) {126ops = &call_ops;127} else if (!strcmp(name, "ret") ||128!strcmp(name, "retl") ||129!strcmp(name, "return")) {130ops = &ret_ops;131} else if (!strcmp(name, "mov")) {132ops = &mov_ops;133} else {134if (name[0] == 'c' &&135(name[1] == 'w' || name[1] == 'x'))136name += 2;137138if (name[0] == 'b') {139const char *cond = name + 1;140141if (cond[0] == 'r') {142if (is_branch_reg_cond(cond + 1))143ops = &jump_ops;144} else if (is_branch_cond(cond)) {145ops = &jump_ops;146}147} else if (name[0] == 'f' && name[1] == 'b') {148if (is_branch_float_cond(name + 2))149ops = &jump_ops;150}151}152153if (ops)154arch__associate_ins_ops(arch, name, ops);155156return ops;157}158159static int sparc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)160{161if (!arch->initialized) {162arch->initialized = true;163arch->associate_instruction_ops = sparc__associate_instruction_ops;164arch->objdump.comment_char = '#';165arch->e_machine = EM_SPARC;166arch->e_flags = 0;167}168169return 0;170}171172173