-
金宝库 authored0df6eb16
/*++
版权 (c) 2023 苗潼超
模块名称:
instsel.c
摘要:
此模块包含指令选择所需的各种例程。
作者:
苗潼超 (mtc) 14-June-2023
修订历史:
14-June-2023 mtc
创建.
--*/
#include "compiler.h"
#include <string.h>
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
static DYNAMIC_ARRAY stackframes;
typedef struct MyData {
struct frame_info *lpFrameInfo;
SYMENT *psymentFunction; // 函数的符号表项
DYNAMIC_ARRAY virtreg; // 虚拟寄存器堆
SYMENT * retval; // 函数的返回值符号表项
basic_block *blkPtr; // 当前基本块
PLLI tailcalls; // 尾调用的集合
int reg_start; // 起始虚拟寄存器。
} MYDATA, *PMYDATA;
char *opCodeTab[] = {
/* 数据传送指令 */
"push", /* 数据传送指令 压栈 */
"pop", /* 数据传送指令 出栈 */
"movw", /* 数据传送指令 movw */
"movt", /* 数据传送指令 movt */
"mov", /* 数据传送指令 mov */
"ldr", /* 数据传送指令 ldr */
"str", /* 数据传送指令 str */
"vmrs", /* 数据传送指令 vmrs */
"vmov", /* 数据传送指令 vmov */
"vldr.32", /* 数据传送指令 vldr.32 */
"vstr.32", /* 数据传送指令 vstr.32 */
"vpush.32", /* 数据传送指令 vpush.32 */
"vpop.32", /* 数据传送指令 vpop.32 */
/* 逻辑操作指令 */
"and", /* 逻辑操作指令 与 */
/* 移位操作指令 */
"uxtb", /* 移位操作指令 uxtb */
"lsr", /* 移位操作指令 逻辑右移 */
"asr", /* 移位操作指令 算术右移 */
"lsl", /* 移位操作指令 逻辑左移 */
/* 算术操作指令 */
"add", /* 算术操作指令 reg(r) = reg(s)+reg(t) */
"sub", /* 算术操作指令 reg(r) = reg(s)-reg(t) */
"mul", /* 算术操作指令 reg(r) = reg(s)*reg(t) */
"sdiv", /* 算术操作指令 reg(r) = reg(s)/reg(t) */
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
"rsb", /* 算术操作指令 reg(r) = reg(t)-reg(s) */
"vneg.f32", /* 算术操作指令 reg(r) = -reg(s) */
"vadd.f32", /* 算术操作指令 reg(r) = reg(s)+reg(t) */
"vsub.f32", /* 算术操作指令 reg(r) = reg(s)-reg(t) */
"vmul.f32", /* 算术操作指令 reg(r) = reg(s)*reg(t) */
"vdiv.f32", /* 算术操作指令 reg(r) = reg(s)*reg(t) */
"vcvt.f32.s32", /* 算术操作指令 convert */
"vcvt.s32.f32", /* 算术操作指令 convert */
/* 其他操作指令 */
/* 比较指令 */
"cmp", /* 比较指令 cmp */
"vcmpe.f32", /* 浮点比较指令 vcmpe.f32 */
/* 跳转指令 */
"bx", /* 跳转指令 间接跳转 */
"b", /* 跳转指令 goto */
"bl", /* 跳转指令 bl */
/* 函数调用相关指令 */
/* pseudo-instructions */
".text", /* 伪指令 .text */
".align", /* 伪指令 .align */
".global", /* 伪指令 .global */
".syntax", /* 伪指令 .syntax */
".arm", /* 伪指令 .arm */
".type", /* 伪指令 .type */
"label:", /* 伪指令 label: */
".size", /* 伪指令 .size */
"@DBG: ", /* 伪指令 调试 */
};
// https://developer.arm.com/documentation/dui0801/l/Condition-Codes/Condition-code-suffixes?lang=en
char *condCodeTab[] = {
"al", /* Always (this is the default) */
"eq", /* Equal */
"ne", /* Not equal */
"cs", /* Carry set (identical to HS) */
"hs", /* Unsigned higher or same (identical to CS) */
"cc", /* Carry clear (identical to LO) */
"lo", /* Unsigned lower (identical to CC) */
"mi", /* Minus or negative result */
"pl", /* Positive or zero result */
"vs", /* Overflow */
"vc", /* No overflow */
"hi", /* Unsigned higher */
"ls", /* Unsigned lower or same */
"ge", /* Signed greater than or equal */
"lt", /* Signed less than */
"gt", /* Signed greater than */
"le", /* Signed less than or equal */
};
static int asm_entry(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMTAB *psymtab, void *lpParam);
static int asm_addexp(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMTAB *psymtab, void *lpParam);
static int asm_assign(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMTAB *psymtab, void *lpParam);
static int asm_exit(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMTAB *psymtab, void *lpParam);
static int asm_assignarray(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMTAB *psymtab, void *lpParam);
static int asm_relexp(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMTAB *psymtab, void *lpParam);
static int asm_goto(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMTAB *psymtab, void *lpParam);
static int asm_arrayassign(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMTAB *psymtab, void *lpParam);
static int asm_dummy(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMTAB *psymtab, void *lpParam);
static int asm_funccall(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMTAB *psymtab, void *lpParam);
static int asm_unaryexp(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMTAB *psymtab, void *lpParam);
static int asm_memset(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMTAB *psymtab, void *lpParam);
static int asm_relexp_value(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMTAB *psymtab, void *lpParam);
static int asm_i2f(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMTAB* psymtab, void* lpParam);
static int asm_f2i(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMTAB* psymtab, void* lpParam);
// ================================================================
struct FUNCMAP
// ================================================================
{