brintos

brintos / linux-shallow public Read only

0
0
Text · 3.6 KiB · 2614c01 Raw
170 lines · c
1// SPDX-License-Identifier: GPL-2.02 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