instsel.c 196.93 KiB
/*++
版权 (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 // ================================================================ {