// SPDX-License-Identifier: GPL-2.0
/*
 * Perf annotate functions.
 *
 * Copyright (C) 2020-2023 Loongson Technology Corporation Limited
 */
#include <stdlib.h>
#include <string.h>
#include <linux/compiler.h>
#include <linux/zalloc.h>
#include "../disasm.h"
#include "../map.h"
#include "../maps.h"
#include "../symbol.h"
#include "../thread.h"

static int loongarch_call__parse(const struct arch *arch, struct ins_operands *ops,
				 struct map_symbol *ms,
				 struct disasm_line *dl __maybe_unused)
{
	char *c, *endptr, *tok, *name;
	struct map *map = ms->map;
	struct addr_map_symbol target;

	c = strchr(ops->raw, '#');
	if (c++ == NULL)
		return -1;

	ops->target.addr = strtoull(c, &endptr, 16);

	name = strchr(endptr, '<');
	name++;

	if (arch->objdump.skip_functions_char &&
	    strchr(name, arch->objdump.skip_functions_char))
		return -1;

	tok = strchr(name, '>');
	if (tok == NULL)
		return -1;

	*tok = '\0';
	ops->target.name = strdup(name);
	*tok = '>';

	if (ops->target.name == NULL)
		return -1;

	target = (struct addr_map_symbol) {
		.ms = { .map = map__get(map), },
		.addr = map__objdump_2mem(map, ops->target.addr),
	};

	if (maps__find_ams(thread__maps(ms->thread), &target) == 0 &&
	    map__rip_2objdump(target.ms.map, map__map_ip(target.ms.map, target.addr)) == ops->target.addr)
		ops->target.sym = target.ms.sym;

	addr_map_symbol__exit(&target);
	return 0;
}

static const struct ins_ops loongarch_call_ops = {
	.parse	   = loongarch_call__parse,
	.scnprintf = call__scnprintf,
	.is_call   = true,
};

static int loongarch_jump__parse(const struct arch *arch, struct ins_operands *ops,
				 struct map_symbol *ms,
				 struct disasm_line *dl __maybe_unused)

{
	struct map *map = ms->map;
	struct symbol *sym = ms->sym;
	struct addr_map_symbol target = {
		.ms = { .map = map__get(map), },
	};
	const char *c = strchr(ops->raw, '#');
	u64 start, end;

	ops->jump.raw_comment = strchr(ops->raw, arch->objdump.comment_char);
	ops->jump.raw_func_start = strchr(ops->raw, '<');

	if (ops->jump.raw_func_start && c > ops->jump.raw_func_start)
		c = NULL;

	if (c++ != NULL)
		ops->target.addr = strtoull(c, NULL, 16);
	else
		ops->target.addr = strtoull(ops->raw, NULL, 16);

	target.addr = map__objdump_2mem(map, ops->target.addr);
	start = map__unmap_ip(map, sym->start);
	end = map__unmap_ip(map, sym->end);

	ops->target.outside = target.addr < start || target.addr >= end;

	if (maps__find_ams(thread__maps(ms->thread), &target) == 0 &&
	    map__rip_2objdump(target.ms.map, map__map_ip(target.ms.map, target.addr)) == ops->target.addr)
		ops->target.sym = target.ms.sym;

	if (!ops->target.outside) {
		ops->target.offset = target.addr - start;
		ops->target.offset_avail = true;
	} else {
		ops->target.offset_avail = false;
	}
	addr_map_symbol__exit(&target);
	return 0;
}

static const struct ins_ops loongarch_jump_ops = {
	.free	   = jump__delete,
	.parse	   = loongarch_jump__parse,
	.scnprintf = jump__scnprintf,
	.is_jump   = true,
};

static
const struct ins_ops *loongarch__associate_ins_ops(struct arch *arch, const char *name)
{
	const struct ins_ops *ops = NULL;

	if (!strcmp(name, "bl"))
		ops = &loongarch_call_ops;
	else if (!strcmp(name, "jirl"))
		ops = &ret_ops;
	else if (!strcmp(name, "b") ||
		 !strncmp(name, "beq", 3) ||
		 !strncmp(name, "bne", 3) ||
		 !strncmp(name, "blt", 3) ||
		 !strncmp(name, "bge", 3) ||
		 !strncmp(name, "bltu", 4) ||
		 !strncmp(name, "bgeu", 4))
		ops = &loongarch_jump_ops;
	else
		return NULL;

	arch__associate_ins_ops(arch, name, ops);

	return ops;
}

const struct arch *arch__new_loongarch(const struct e_machine_and_e_flags *id,
				       const char *cpuid __maybe_unused)
{
	struct arch *arch = zalloc(sizeof(*arch));

	if (!arch)
		return NULL;

	arch->name = "loongarch";
	arch->id = *id;
	arch->associate_instruction_ops = loongarch__associate_ins_ops;
	arch->objdump.comment_char = '#';
	return arch;
}
