<commit_before>
#include <assert.h>
#include <stdarg.h>
#include <inttypes.h>
#include <stdlib.h>

#include "../inc/cc.h"
#include "cc2.h"


static Node *reguse[NREGS];
static char upper[] = {[DE] = D, [HL] = H, [BC] = B,  [IY] = IYH};
static char lower[] = {[DE] = E, [HL] = L, [BC] = C, [IY] = IYL};
static char pair[] = {
	[A] = A,
	[H] = HL, [L] = HL,
	[B] = BC, [C] = BC,
	[D] = DE, [E] = DE,
	[IYL] = IY, [IYH] = IY
};

Node
reg_E = {
	.op = REG,
	.reg = E
},
reg_D = {
	.op = REG,
	.reg = D
},
reg_H = {
	.op = REG,
	.reg = H
},
reg_L = {
	.op = REG,
	.reg = L
},
reg_C = {
	.op= REG,
	.reg = C
},
reg_B = {
	.op= REG,
	.reg = B
},
reg_A = {
	.op= REG,
	.reg = A
},
reg_IYL = {
	.op = REG,
	.reg = IYL
},
reg_IYH = {
	.op = REG,
	.reg = IYH
},
reg_DE = {
	.op = REG,
	.reg = DE
},
reg_HL = {
	.op = REG,
	.reg = HL
},
reg_BC = {
	.op = REG,
	.reg = BC
},
reg_IX = {
	.op = REG,
	.reg = IX
},
reg_IY = {
	.op = REG,
	.reg = IY
},
reg_SP = {
	.op = REG,
	.reg = SP
};

Node *regs[] = {
	[A] = &reg_A,
	[B] = &reg_B, [C] = &reg_C,
	[D] = &reg_D, [E] = &reg_E,
	[H] = &reg_H, [L] = &reg_L,
	[IYL] = &reg_IYL, [IYH] = &reg_IYH,
	[HL] = &reg_HL, [DE] = &reg_DE, [BC]= &reg_BC,
	[IX] = &reg_IX, [IY] = &reg_IY, [SP] = &reg_SP
};

static char
allocreg(Node *np)
{
	static char reg8[] = {A, B, C, D, E, H, L, IYL, IY, 0};
	static char reg16[] = {BC, DE, IY, 0};
	char *bp, c;

	switch (np->type.size) {
	case 1:
		for (bp = reg8; (c = *bp); ++bp) {
			if (reguse[c])
				continue;
			reguse[c] = np;
			return c;
		}
		/* TODO: Move variable to stack using PUSH/POP */
		break;
	case 2:
		for (bp = reg16; (c = *bp); ++bp) {
			char u = upper[c], l = lower[c];

			if (reguse[u] || reguse[l])
				continue;
			reguse[u] = reguse[l] = np;
			return c;
		}
		/* TODO: Move variable to stack using PUSH/POP */
		break;
	}
	abort();
}

static void
moveto(Node *np, uint8_t reg)
{
	Symbol *sym;

	switch (np->op) {
	case CONST:
		switch (np->type.size) {
		case 1:
		case 2:
			code(LDI, regs[reg], np);
			break;
		default:
			abort();
		}
		break;
	case AUTO:
		sym = np->sym;
		switch (np->type.size) {
		case 1:
			code(LDL, regs[reg], np);
			break;
		case 2:
			code(LDL, regs[lower[reg]], np);
			code(LDH, regs[upper[reg]], np);
			break;
		case 4:
		case 8:
		default:
			abort();
		}
		break;
	default:
		abort();
	}
	np->op = REG;
	np->reg = reg;
}

static void
move(Node *np)
{
	moveto(np, allocreg(np));
}

static void
push(uint8_t reg)<commit_msg>Inver switch order in moveto()<commit_after>
#include <stdarg.h>
#include <inttypes.h>
#include <stdlib.h>

#include "../inc/cc.h"
#include "cc2.h"


static Node *reguse[NREGS];
static char upper[] = {[DE] = D, [HL] = H, [BC] = B,  [IY] = IYH};
static char lower[] = {[DE] = E, [HL] = L, [BC] = C, [IY] = IYL};
static char pair[] = {
	[A] = A,
	[H] = HL, [L] = HL,
	[B] = BC, [C] = BC,
	[D] = DE, [E] = DE,
	[IYL] = IY, [IYH] = IY
};

Node
reg_E = {
	.op = REG,
	.reg = E
},
reg_D = {
	.op = REG,
	.reg = D
},
reg_H = {
	.op = REG,
	.reg = H
},
reg_L = {
	.op = REG,
	.reg = L
},
reg_C = {
	.op= REG,
	.reg = C
},
reg_B = {
	.op= REG,
	.reg = B
},
reg_A = {
	.op= REG,
	.reg = A
},
reg_IYL = {
	.op = REG,
	.reg = IYL
},
reg_IYH = {
	.op = REG,
	.reg = IYH
},
reg_DE = {
	.op = REG,
	.reg = DE
},
reg_HL = {
	.op = REG,
	.reg = HL
},
reg_BC = {
	.op = REG,
	.reg = BC
},
reg_IX = {
	.op = REG,
	.reg = IX
},
reg_IY = {
	.op = REG,
	.reg = IY
},
reg_SP = {
	.op = REG,
	.reg = SP
};

Node *regs[] = {
	[A] = &reg_A,
	[B] = &reg_B, [C] = &reg_C,
	[D] = &reg_D, [E] = &reg_E,
	[H] = &reg_H, [L] = &reg_L,
	[IYL] = &reg_IYL, [IYH] = &reg_IYH,
	[HL] = &reg_HL, [DE] = &reg_DE, [BC]= &reg_BC,
	[IX] = &reg_IX, [IY] = &reg_IY, [SP] = &reg_SP
};

static char
allocreg(Node *np)
{
	static char reg8[] = {A, B, C, D, E, H, L, IYL, IY, 0};
	static char reg16[] = {BC, DE, IY, 0};
	char *bp, c;

	switch (np->type.size) {
	case 1:
		for (bp = reg8; (c = *bp); ++bp) {
			if (reguse[c])
				continue;
			reguse[c] = np;
			return c;
		}
		/* TODO: Move variable to stack using PUSH/POP */
		break;
	case 2:
		for (bp = reg16; (c = *bp); ++bp) {
			char u = upper[c], l = lower[c];

			if (reguse[u] || reguse[l])
				continue;
			reguse[u] = reguse[l] = np;
			return c;
		}
		/* TODO: Move variable to stack using PUSH/POP */
		break;
	}
	abort();
}

static void
moveto(Node *np, uint8_t reg)
{
	Symbol *sym = np->sym;
	char op = np->op;

	switch (np->type.size) {
	case 1:
		switch (op) {
		case CONST:
			code(LDI, regs[reg], np);
			break;
		case AUTO:
			code(LDL, regs[reg], np);
			break;
		default:
			abort();
		}
		break;
	case 2:
		switch (op) {
		case CONST:
			code(LDL, regs[reg], np);
			break;
		case AUTO:
			code(LDL, regs[lower[reg]], np);
			code(LDH, regs[upper[reg]], np);
			break;
		default:
			abort();
		}
		break;
	default:
		abort();
	}
	np->op = REG;
	np->reg = reg;
}

static void
move(Node *np)
{
	moveto(np, allocreg(np));
}

static void
push(uint8_t reg)
{'fraction_non_alphanumeric': 0.2288961038961039, 'fraction_numerical': 0.006899350649350649, 'mean_word_length': 2.520714285714286, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5149518', 'n_tokens_mistral': 2696, 'n_tokens_neox': 2522, 'n_words': 641}