linux/tools/perf/arch/sparc/annotate/instructions.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2
   3static int is_branch_cond(const char *cond)
   4{
   5        if (cond[0] == '\0')
   6                return 1;
   7
   8        if (cond[0] == 'a' && cond[1] == '\0')
   9                return 1;
  10
  11        if (cond[0] == 'c' &&
  12            (cond[1] == 'c' || cond[1] == 's') &&
  13            cond[2] == '\0')
  14                return 1;
  15
  16        if (cond[0] == 'e' &&
  17            (cond[1] == '\0' ||
  18             (cond[1] == 'q' && cond[2] == '\0')))
  19                return 1;
  20
  21        if (cond[0] == 'g' &&
  22            (cond[1] == '\0' ||
  23             (cond[1] == 't' && cond[2] == '\0') ||
  24             (cond[1] == 'e' && cond[2] == '\0') ||
  25             (cond[1] == 'e' && cond[2] == 'u' && cond[3] == '\0')))
  26                return 1;
  27
  28        if (cond[0] == 'l' &&
  29            (cond[1] == '\0' ||
  30             (cond[1] == 't' && cond[2] == '\0') ||
  31             (cond[1] == 'u' && cond[2] == '\0') ||
  32             (cond[1] == 'e' && cond[2] == '\0') ||
  33             (cond[1] == 'e' && cond[2] == 'u' && cond[3] == '\0')))
  34                return 1;
  35
  36        if (cond[0] == 'n' &&
  37            (cond[1] == '\0' ||
  38             (cond[1] == 'e' && cond[2] == '\0') ||
  39             (cond[1] == 'z' && cond[2] == '\0') ||
  40             (cond[1] == 'e' && cond[2] == 'g' && cond[3] == '\0')))
  41                return 1;
  42
  43        if (cond[0] == 'b' &&
  44            cond[1] == 'p' &&
  45            cond[2] == 'o' &&
  46            cond[3] == 's' &&
  47            cond[4] == '\0')
  48                return 1;
  49
  50        if (cond[0] == 'v' &&
  51            (cond[1] == 'c' || cond[1] == 's') &&
  52            cond[2] == '\0')
  53                return 1;
  54
  55        if (cond[0] == 'b' &&
  56            cond[1] == 'z' &&
  57            cond[2] == '\0')
  58                return 1;
  59
  60        return 0;
  61}
  62
  63static int is_branch_reg_cond(const char *cond)
  64{
  65        if ((cond[0] == 'n' || cond[0] == 'l') &&
  66            cond[1] == 'z' &&
  67            cond[2] == '\0')
  68                return 1;
  69
  70        if (cond[0] == 'z' &&
  71            cond[1] == '\0')
  72                return 1;
  73
  74        if ((cond[0] == 'g' || cond[0] == 'l') &&
  75            cond[1] == 'e' &&
  76            cond[2] == 'z' &&
  77            cond[3] == '\0')
  78                return 1;
  79
  80        if (cond[0] == 'g' &&
  81            cond[1] == 'z' &&
  82            cond[2] == '\0')
  83                return 1;
  84
  85        return 0;
  86}
  87
  88static int is_branch_float_cond(const char *cond)
  89{
  90        if (cond[0] == '\0')
  91                return 1;
  92
  93        if ((cond[0] == 'a' || cond[0] == 'e' ||
  94             cond[0] == 'z' || cond[0] == 'g' ||
  95             cond[0] == 'l' || cond[0] == 'n' ||
  96             cond[0] == 'o' || cond[0] == 'u') &&
  97            cond[1] == '\0')
  98                return 1;
  99
 100        if (((cond[0] == 'g' && cond[1] == 'e') ||
 101             (cond[0] == 'l' && (cond[1] == 'e' ||
 102                                 cond[1] == 'g')) ||
 103             (cond[0] == 'n' && (cond[1] == 'e' ||
 104                                 cond[1] == 'z')) ||
 105             (cond[0] == 'u' && (cond[1] == 'e' ||
 106                                 cond[1] == 'g' ||
 107                                 cond[1] == 'l'))) &&
 108            cond[2] == '\0')
 109                return 1;
 110
 111        if (cond[0] == 'u' &&
 112            (cond[1] == 'g' || cond[1] == 'l') &&
 113            cond[2] == 'e' &&
 114            cond[3] == '\0')
 115                return 1;
 116
 117        return 0;
 118}
 119
 120static struct ins_ops *sparc__associate_instruction_ops(struct arch *arch, const char *name)
 121{
 122        struct ins_ops *ops = NULL;
 123
 124        if (!strcmp(name, "call") ||
 125            !strcmp(name, "jmp") ||
 126            !strcmp(name, "jmpl")) {
 127                ops = &call_ops;
 128        } else if (!strcmp(name, "ret") ||
 129                   !strcmp(name, "retl") ||
 130                   !strcmp(name, "return")) {
 131                ops = &ret_ops;
 132        } else if (!strcmp(name, "mov")) {
 133                ops = &mov_ops;
 134        } else {
 135                if (name[0] == 'c' &&
 136                    (name[1] == 'w' || name[1] == 'x'))
 137                        name += 2;
 138
 139                if (name[0] == 'b') {
 140                        const char *cond = name + 1;
 141
 142                        if (cond[0] == 'r') {
 143                                if (is_branch_reg_cond(cond + 1))
 144                                        ops = &jump_ops;
 145                        } else if (is_branch_cond(cond)) {
 146                                ops = &jump_ops;
 147                        }
 148                } else if (name[0] == 'f' && name[1] == 'b') {
 149                        if (is_branch_float_cond(name + 2))
 150                                ops = &jump_ops;
 151                }
 152        }
 153
 154        if (ops)
 155                arch__associate_ins_ops(arch, name, ops);
 156
 157        return ops;
 158}
 159
 160static int sparc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
 161{
 162        if (!arch->initialized) {
 163                arch->initialized = true;
 164                arch->associate_instruction_ops = sparc__associate_instruction_ops;
 165                arch->objdump.comment_char = '#';
 166        }
 167
 168        return 0;
 169}
 170