0001
0002
0003 static int is_branch_cond(const char *cond)
0004 {
0005 if (cond[0] == '\0')
0006 return 1;
0007
0008 if (cond[0] == 'a' && cond[1] == '\0')
0009 return 1;
0010
0011 if (cond[0] == 'c' &&
0012 (cond[1] == 'c' || cond[1] == 's') &&
0013 cond[2] == '\0')
0014 return 1;
0015
0016 if (cond[0] == 'e' &&
0017 (cond[1] == '\0' ||
0018 (cond[1] == 'q' && cond[2] == '\0')))
0019 return 1;
0020
0021 if (cond[0] == 'g' &&
0022 (cond[1] == '\0' ||
0023 (cond[1] == 't' && cond[2] == '\0') ||
0024 (cond[1] == 'e' && cond[2] == '\0') ||
0025 (cond[1] == 'e' && cond[2] == 'u' && cond[3] == '\0')))
0026 return 1;
0027
0028 if (cond[0] == 'l' &&
0029 (cond[1] == '\0' ||
0030 (cond[1] == 't' && cond[2] == '\0') ||
0031 (cond[1] == 'u' && cond[2] == '\0') ||
0032 (cond[1] == 'e' && cond[2] == '\0') ||
0033 (cond[1] == 'e' && cond[2] == 'u' && cond[3] == '\0')))
0034 return 1;
0035
0036 if (cond[0] == 'n' &&
0037 (cond[1] == '\0' ||
0038 (cond[1] == 'e' && cond[2] == '\0') ||
0039 (cond[1] == 'z' && cond[2] == '\0') ||
0040 (cond[1] == 'e' && cond[2] == 'g' && cond[3] == '\0')))
0041 return 1;
0042
0043 if (cond[0] == 'b' &&
0044 cond[1] == 'p' &&
0045 cond[2] == 'o' &&
0046 cond[3] == 's' &&
0047 cond[4] == '\0')
0048 return 1;
0049
0050 if (cond[0] == 'v' &&
0051 (cond[1] == 'c' || cond[1] == 's') &&
0052 cond[2] == '\0')
0053 return 1;
0054
0055 if (cond[0] == 'b' &&
0056 cond[1] == 'z' &&
0057 cond[2] == '\0')
0058 return 1;
0059
0060 return 0;
0061 }
0062
0063 static int is_branch_reg_cond(const char *cond)
0064 {
0065 if ((cond[0] == 'n' || cond[0] == 'l') &&
0066 cond[1] == 'z' &&
0067 cond[2] == '\0')
0068 return 1;
0069
0070 if (cond[0] == 'z' &&
0071 cond[1] == '\0')
0072 return 1;
0073
0074 if ((cond[0] == 'g' || cond[0] == 'l') &&
0075 cond[1] == 'e' &&
0076 cond[2] == 'z' &&
0077 cond[3] == '\0')
0078 return 1;
0079
0080 if (cond[0] == 'g' &&
0081 cond[1] == 'z' &&
0082 cond[2] == '\0')
0083 return 1;
0084
0085 return 0;
0086 }
0087
0088 static int is_branch_float_cond(const char *cond)
0089 {
0090 if (cond[0] == '\0')
0091 return 1;
0092
0093 if ((cond[0] == 'a' || cond[0] == 'e' ||
0094 cond[0] == 'z' || cond[0] == 'g' ||
0095 cond[0] == 'l' || cond[0] == 'n' ||
0096 cond[0] == 'o' || cond[0] == 'u') &&
0097 cond[1] == '\0')
0098 return 1;
0099
0100 if (((cond[0] == 'g' && cond[1] == 'e') ||
0101 (cond[0] == 'l' && (cond[1] == 'e' ||
0102 cond[1] == 'g')) ||
0103 (cond[0] == 'n' && (cond[1] == 'e' ||
0104 cond[1] == 'z')) ||
0105 (cond[0] == 'u' && (cond[1] == 'e' ||
0106 cond[1] == 'g' ||
0107 cond[1] == 'l'))) &&
0108 cond[2] == '\0')
0109 return 1;
0110
0111 if (cond[0] == 'u' &&
0112 (cond[1] == 'g' || cond[1] == 'l') &&
0113 cond[2] == 'e' &&
0114 cond[3] == '\0')
0115 return 1;
0116
0117 return 0;
0118 }
0119
0120 static struct ins_ops *sparc__associate_instruction_ops(struct arch *arch, const char *name)
0121 {
0122 struct ins_ops *ops = NULL;
0123
0124 if (!strcmp(name, "call") ||
0125 !strcmp(name, "jmp") ||
0126 !strcmp(name, "jmpl")) {
0127 ops = &call_ops;
0128 } else if (!strcmp(name, "ret") ||
0129 !strcmp(name, "retl") ||
0130 !strcmp(name, "return")) {
0131 ops = &ret_ops;
0132 } else if (!strcmp(name, "mov")) {
0133 ops = &mov_ops;
0134 } else {
0135 if (name[0] == 'c' &&
0136 (name[1] == 'w' || name[1] == 'x'))
0137 name += 2;
0138
0139 if (name[0] == 'b') {
0140 const char *cond = name + 1;
0141
0142 if (cond[0] == 'r') {
0143 if (is_branch_reg_cond(cond + 1))
0144 ops = &jump_ops;
0145 } else if (is_branch_cond(cond)) {
0146 ops = &jump_ops;
0147 }
0148 } else if (name[0] == 'f' && name[1] == 'b') {
0149 if (is_branch_float_cond(name + 2))
0150 ops = &jump_ops;
0151 }
0152 }
0153
0154 if (ops)
0155 arch__associate_ins_ops(arch, name, ops);
0156
0157 return ops;
0158 }
0159
0160 static int sparc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
0161 {
0162 if (!arch->initialized) {
0163 arch->initialized = true;
0164 arch->associate_instruction_ops = sparc__associate_instruction_ops;
0165 arch->objdump.comment_char = '#';
0166 }
0167
0168 return 0;
0169 }