162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci 362306a36Sopenharmony_cistatic int is_branch_cond(const char *cond) 462306a36Sopenharmony_ci{ 562306a36Sopenharmony_ci if (cond[0] == '\0') 662306a36Sopenharmony_ci return 1; 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci if (cond[0] == 'a' && cond[1] == '\0') 962306a36Sopenharmony_ci return 1; 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci if (cond[0] == 'c' && 1262306a36Sopenharmony_ci (cond[1] == 'c' || cond[1] == 's') && 1362306a36Sopenharmony_ci cond[2] == '\0') 1462306a36Sopenharmony_ci return 1; 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci if (cond[0] == 'e' && 1762306a36Sopenharmony_ci (cond[1] == '\0' || 1862306a36Sopenharmony_ci (cond[1] == 'q' && cond[2] == '\0'))) 1962306a36Sopenharmony_ci return 1; 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci if (cond[0] == 'g' && 2262306a36Sopenharmony_ci (cond[1] == '\0' || 2362306a36Sopenharmony_ci (cond[1] == 't' && cond[2] == '\0') || 2462306a36Sopenharmony_ci (cond[1] == 'e' && cond[2] == '\0') || 2562306a36Sopenharmony_ci (cond[1] == 'e' && cond[2] == 'u' && cond[3] == '\0'))) 2662306a36Sopenharmony_ci return 1; 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci if (cond[0] == 'l' && 2962306a36Sopenharmony_ci (cond[1] == '\0' || 3062306a36Sopenharmony_ci (cond[1] == 't' && cond[2] == '\0') || 3162306a36Sopenharmony_ci (cond[1] == 'u' && cond[2] == '\0') || 3262306a36Sopenharmony_ci (cond[1] == 'e' && cond[2] == '\0') || 3362306a36Sopenharmony_ci (cond[1] == 'e' && cond[2] == 'u' && cond[3] == '\0'))) 3462306a36Sopenharmony_ci return 1; 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci if (cond[0] == 'n' && 3762306a36Sopenharmony_ci (cond[1] == '\0' || 3862306a36Sopenharmony_ci (cond[1] == 'e' && cond[2] == '\0') || 3962306a36Sopenharmony_ci (cond[1] == 'z' && cond[2] == '\0') || 4062306a36Sopenharmony_ci (cond[1] == 'e' && cond[2] == 'g' && cond[3] == '\0'))) 4162306a36Sopenharmony_ci return 1; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci if (cond[0] == 'b' && 4462306a36Sopenharmony_ci cond[1] == 'p' && 4562306a36Sopenharmony_ci cond[2] == 'o' && 4662306a36Sopenharmony_ci cond[3] == 's' && 4762306a36Sopenharmony_ci cond[4] == '\0') 4862306a36Sopenharmony_ci return 1; 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci if (cond[0] == 'v' && 5162306a36Sopenharmony_ci (cond[1] == 'c' || cond[1] == 's') && 5262306a36Sopenharmony_ci cond[2] == '\0') 5362306a36Sopenharmony_ci return 1; 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci if (cond[0] == 'b' && 5662306a36Sopenharmony_ci cond[1] == 'z' && 5762306a36Sopenharmony_ci cond[2] == '\0') 5862306a36Sopenharmony_ci return 1; 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci return 0; 6162306a36Sopenharmony_ci} 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_cistatic int is_branch_reg_cond(const char *cond) 6462306a36Sopenharmony_ci{ 6562306a36Sopenharmony_ci if ((cond[0] == 'n' || cond[0] == 'l') && 6662306a36Sopenharmony_ci cond[1] == 'z' && 6762306a36Sopenharmony_ci cond[2] == '\0') 6862306a36Sopenharmony_ci return 1; 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci if (cond[0] == 'z' && 7162306a36Sopenharmony_ci cond[1] == '\0') 7262306a36Sopenharmony_ci return 1; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci if ((cond[0] == 'g' || cond[0] == 'l') && 7562306a36Sopenharmony_ci cond[1] == 'e' && 7662306a36Sopenharmony_ci cond[2] == 'z' && 7762306a36Sopenharmony_ci cond[3] == '\0') 7862306a36Sopenharmony_ci return 1; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci if (cond[0] == 'g' && 8162306a36Sopenharmony_ci cond[1] == 'z' && 8262306a36Sopenharmony_ci cond[2] == '\0') 8362306a36Sopenharmony_ci return 1; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci return 0; 8662306a36Sopenharmony_ci} 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_cistatic int is_branch_float_cond(const char *cond) 8962306a36Sopenharmony_ci{ 9062306a36Sopenharmony_ci if (cond[0] == '\0') 9162306a36Sopenharmony_ci return 1; 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci if ((cond[0] == 'a' || cond[0] == 'e' || 9462306a36Sopenharmony_ci cond[0] == 'z' || cond[0] == 'g' || 9562306a36Sopenharmony_ci cond[0] == 'l' || cond[0] == 'n' || 9662306a36Sopenharmony_ci cond[0] == 'o' || cond[0] == 'u') && 9762306a36Sopenharmony_ci cond[1] == '\0') 9862306a36Sopenharmony_ci return 1; 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci if (((cond[0] == 'g' && cond[1] == 'e') || 10162306a36Sopenharmony_ci (cond[0] == 'l' && (cond[1] == 'e' || 10262306a36Sopenharmony_ci cond[1] == 'g')) || 10362306a36Sopenharmony_ci (cond[0] == 'n' && (cond[1] == 'e' || 10462306a36Sopenharmony_ci cond[1] == 'z')) || 10562306a36Sopenharmony_ci (cond[0] == 'u' && (cond[1] == 'e' || 10662306a36Sopenharmony_ci cond[1] == 'g' || 10762306a36Sopenharmony_ci cond[1] == 'l'))) && 10862306a36Sopenharmony_ci cond[2] == '\0') 10962306a36Sopenharmony_ci return 1; 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci if (cond[0] == 'u' && 11262306a36Sopenharmony_ci (cond[1] == 'g' || cond[1] == 'l') && 11362306a36Sopenharmony_ci cond[2] == 'e' && 11462306a36Sopenharmony_ci cond[3] == '\0') 11562306a36Sopenharmony_ci return 1; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci return 0; 11862306a36Sopenharmony_ci} 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_cistatic struct ins_ops *sparc__associate_instruction_ops(struct arch *arch, const char *name) 12162306a36Sopenharmony_ci{ 12262306a36Sopenharmony_ci struct ins_ops *ops = NULL; 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci if (!strcmp(name, "call") || 12562306a36Sopenharmony_ci !strcmp(name, "jmp") || 12662306a36Sopenharmony_ci !strcmp(name, "jmpl")) { 12762306a36Sopenharmony_ci ops = &call_ops; 12862306a36Sopenharmony_ci } else if (!strcmp(name, "ret") || 12962306a36Sopenharmony_ci !strcmp(name, "retl") || 13062306a36Sopenharmony_ci !strcmp(name, "return")) { 13162306a36Sopenharmony_ci ops = &ret_ops; 13262306a36Sopenharmony_ci } else if (!strcmp(name, "mov")) { 13362306a36Sopenharmony_ci ops = &mov_ops; 13462306a36Sopenharmony_ci } else { 13562306a36Sopenharmony_ci if (name[0] == 'c' && 13662306a36Sopenharmony_ci (name[1] == 'w' || name[1] == 'x')) 13762306a36Sopenharmony_ci name += 2; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci if (name[0] == 'b') { 14062306a36Sopenharmony_ci const char *cond = name + 1; 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci if (cond[0] == 'r') { 14362306a36Sopenharmony_ci if (is_branch_reg_cond(cond + 1)) 14462306a36Sopenharmony_ci ops = &jump_ops; 14562306a36Sopenharmony_ci } else if (is_branch_cond(cond)) { 14662306a36Sopenharmony_ci ops = &jump_ops; 14762306a36Sopenharmony_ci } 14862306a36Sopenharmony_ci } else if (name[0] == 'f' && name[1] == 'b') { 14962306a36Sopenharmony_ci if (is_branch_float_cond(name + 2)) 15062306a36Sopenharmony_ci ops = &jump_ops; 15162306a36Sopenharmony_ci } 15262306a36Sopenharmony_ci } 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci if (ops) 15562306a36Sopenharmony_ci arch__associate_ins_ops(arch, name, ops); 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci return ops; 15862306a36Sopenharmony_ci} 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_cistatic int sparc__annotate_init(struct arch *arch, char *cpuid __maybe_unused) 16162306a36Sopenharmony_ci{ 16262306a36Sopenharmony_ci if (!arch->initialized) { 16362306a36Sopenharmony_ci arch->initialized = true; 16462306a36Sopenharmony_ci arch->associate_instruction_ops = sparc__associate_instruction_ops; 16562306a36Sopenharmony_ci arch->objdump.comment_char = '#'; 16662306a36Sopenharmony_ci } 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci return 0; 16962306a36Sopenharmony_ci} 170