// SPDX-License-Identifier: GPL-2.0
#include <errno.h>
#include <regex.h>
#include <string.h>
#include <sys/auxv.h>
#include <linux/kernel.h>
#include <linux/zalloc.h>

#include "perf_regs.h"
#include "../../../perf-sys.h"
#include "../../../util/debug.h"
#include "../../../util/event.h"
#include "../../../util/perf_regs.h"

#ifndef HWCAP_SVE
#define HWCAP_SVE	(1 << 22)
#endif

const struct sample_reg sample_reg_masks[] = {
	SMPL_REG(x0, PERF_REG_ARM64_X0),
	SMPL_REG(x1, PERF_REG_ARM64_X1),
	SMPL_REG(x2, PERF_REG_ARM64_X2),
	SMPL_REG(x3, PERF_REG_ARM64_X3),
	SMPL_REG(x4, PERF_REG_ARM64_X4),
	SMPL_REG(x5, PERF_REG_ARM64_X5),
	SMPL_REG(x6, PERF_REG_ARM64_X6),
	SMPL_REG(x7, PERF_REG_ARM64_X7),
	SMPL_REG(x8, PERF_REG_ARM64_X8),
	SMPL_REG(x9, PERF_REG_ARM64_X9),
	SMPL_REG(x10, PERF_REG_ARM64_X10),
	SMPL_REG(x11, PERF_REG_ARM64_X11),
	SMPL_REG(x12, PERF_REG_ARM64_X12),
	SMPL_REG(x13, PERF_REG_ARM64_X13),
	SMPL_REG(x14, PERF_REG_ARM64_X14),
	SMPL_REG(x15, PERF_REG_ARM64_X15),
	SMPL_REG(x16, PERF_REG_ARM64_X16),
	SMPL_REG(x17, PERF_REG_ARM64_X17),
	SMPL_REG(x18, PERF_REG_ARM64_X18),
	SMPL_REG(x19, PERF_REG_ARM64_X19),
	SMPL_REG(x20, PERF_REG_ARM64_X20),
	SMPL_REG(x21, PERF_REG_ARM64_X21),
	SMPL_REG(x22, PERF_REG_ARM64_X22),
	SMPL_REG(x23, PERF_REG_ARM64_X23),
	SMPL_REG(x24, PERF_REG_ARM64_X24),
	SMPL_REG(x25, PERF_REG_ARM64_X25),
	SMPL_REG(x26, PERF_REG_ARM64_X26),
	SMPL_REG(x27, PERF_REG_ARM64_X27),
	SMPL_REG(x28, PERF_REG_ARM64_X28),
	SMPL_REG(x29, PERF_REG_ARM64_X29),
	SMPL_REG(lr, PERF_REG_ARM64_LR),
	SMPL_REG(sp, PERF_REG_ARM64_SP),
	SMPL_REG(pc, PERF_REG_ARM64_PC),
	SMPL_REG(vg, PERF_REG_ARM64_VG),
	SMPL_REG_END
};

/* %xNUM */
#define SDT_OP_REGEX1  "^(x[1-2]?[0-9]|3[0-1])$"

/* [sp], [sp, NUM] */
#define SDT_OP_REGEX2  "^\\[sp(, )?([0-9]+)?\\]$"

static regex_t sdt_op_regex1, sdt_op_regex2;

static int sdt_init_op_regex(void)
{
	static int initialized;
	int ret = 0;

	if (initialized)
		return 0;

	ret = regcomp(&sdt_op_regex1, SDT_OP_REGEX1, REG_EXTENDED);
	if (ret)
		goto error;

	ret = regcomp(&sdt_op_regex2, SDT_OP_REGEX2, REG_EXTENDED);
	if (ret)
		goto free_regex1;

	initialized = 1;
	return 0;

free_regex1:
	regfree(&sdt_op_regex1);
error:
	pr_debug4("Regex compilation error.\n");
	return ret;
}

/*
 * SDT marker arguments on Arm64 uses %xREG or [sp, NUM], currently
 * support these two formats.
 */
int arch_sdt_arg_parse_op(char *old_op, char **new_op)
{
	int ret, new_len;
	regmatch_t rm[5];

	ret = sdt_init_op_regex();
	if (ret < 0)
		return ret;

	if (!regexec(&sdt_op_regex1, old_op, 3, rm, 0)) {
		/* Extract xNUM */
		new_len = 2;	/* % NULL */
		new_len += (int)(rm[1].rm_eo - rm[1].rm_so);

		*new_op = zalloc(new_len);
		if (!*new_op)
			return -ENOMEM;

		scnprintf(*new_op, new_len, "%%%.*s",
			(int)(rm[1].rm_eo - rm[1].rm_so), old_op + rm[1].rm_so);
	} else if (!regexec(&sdt_op_regex2, old_op, 5, rm, 0)) {
		/* [sp], [sp, NUM] or [sp,NUM] */
		new_len = 7;	/* + ( % s p ) NULL */

		/* If the argument is [sp], need to fill offset '0' */
		if (rm[2].rm_so == -1)
			new_len += 1;
		else
			new_len += (int)(rm[2].rm_eo - rm[2].rm_so);

		*new_op = zalloc(new_len);
		if (!*new_op)
			return -ENOMEM;

		if (rm[2].rm_so == -1)
			scnprintf(*new_op, new_len, "+0(%%sp)");
		else
			scnprintf(*new_op, new_len, "+%.*s(%%sp)",
				  (int)(rm[2].rm_eo - rm[2].rm_so),
				  old_op + rm[2].rm_so);
	} else {
		pr_debug4("Skipping unsupported SDT argument: %s\n", old_op);
		return SDT_ARG_SKIP;
	}

	return SDT_ARG_VALID;
}

uint64_t arch__intr_reg_mask(void)
{
	return PERF_REGS_MASK;
}

uint64_t arch__user_reg_mask(void)
{
	struct perf_event_attr attr = {
		.type                   = PERF_TYPE_HARDWARE,
		.config                 = PERF_COUNT_HW_CPU_CYCLES,
		.sample_type            = PERF_SAMPLE_REGS_USER,
		.disabled               = 1,
		.exclude_kernel         = 1,
		.sample_period		= 1,
		.sample_regs_user	= PERF_REGS_MASK
	};
	int fd;

	if (getauxval(AT_HWCAP) & HWCAP_SVE)
		attr.sample_regs_user |= SMPL_REG_MASK(PERF_REG_ARM64_VG);

	/*
	 * Check if the pmu supports perf extended regs, before
	 * returning the register mask to sample.
	 */
	if (attr.sample_regs_user != PERF_REGS_MASK) {
		event_attr_init(&attr);
		fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
		if (fd != -1) {
			close(fd);
			return attr.sample_regs_user;
		}
	}
	return PERF_REGS_MASK;
}
