Mercurial > hg > Members > kono > compiler-examples
view s-code-llvm.c @ 26:8550260c18fa
fix aarch on mac and llvm
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 18 Oct 2024 16:06:51 +0900 |
parents | 230d5ca49f9f |
children | c4e2ca100ab9 |
line wrap: on
line source
/* Very Simple Code Generator for Intel x86 $Id$ */ #include "s-compile.h" int label = 0; char *comments = "; "; static char *intro[] = { "; ModuleID = 'tmp.c'\n", "source_filename = \"tmp.c\"\n", "target datalayout = \"e-m:o-i64:64-i128:128-n32:64-S128\"\n", "target triple = \"arm64-apple-macosx14.0.0"\n", "\n", "@a = global i64 4, align 8\n", "@b = global i64 3, align 8\n", "@p = global i64 3, align 8\n", "@.str = private unnamed_addr constant [5 x i8] c\"%ld\0A\00\", align 1\n", "@v = common global [100 x i64] zeroinitializer, align 8\n", "\n", "; Function Attrs: noinline nounwind optnone ssp uwtable(sync)\n", "define void @print(i64 noundef %0) #0 {\n", " %2 = alloca i64, align 8\n", " store i64 %0, ptr %2, align 8\n", " %3 = load i64, ptr %2, align 8\n", " %4 = call i32 (ptr, ...) @printf(ptr noundef @.str, i64 noundef %3)\n", " ret void\n", "}\n", "\n", "declare i32 @printf(ptr noundef, ...) #1\n", "\n", "; Function Attrs: noinline nounwind optnone ssp uwtable(sync)\n", "define i32 @main() #0 {\n", " %1 = alloca i32, align 4\n", " store i32 0, ptr %1, align 4\n", " %2 = load i64, ptr @a, align 8\n", " %3 = add nsw i64 %2, 1\n", " %4 = load i64, ptr @b, align 8\n", " %5 = sub nsw i64 %4, 123\n", " %6 = sub nsw i64 %3, %5\n", "", NULL }; static char *ending[] = { " store i64 %6, ptr @a, align 8\n", " %7 = load i64, ptr @a, align 8\n", " call void @print(i64 noundef %7)\n", " %8 = load i64, ptr @p, align 8\n", " %9 = getelementptr inbounds [100 x i64], ptr @v, i64 0, i64 %8\n", " store i64 3, ptr %9, align 8\n", " %10 = load i64, ptr @p, align 8\n", " %11 = getelementptr inbounds [100 x i64], ptr @v, i64 0, i64 %10\n", " %12 = load i64, ptr %11, align 8\n", " call void @print(i64 noundef %12)\n", " %13 = load i64, ptr @a, align 8\n", " %14 = trunc i64 %13 to i32\n", " ret i32 %14\n", "}\n", "\n", "attributes #0 = { noinline nounwind optnone ssp uwtable(sync) \"frame-pointer\"=\"non-leaf\" \"min-legal-vector-width\"=\"0\" \"no-trapping-math\"=\"true\" \"probe-stack\"=\"__chkstk_darwin\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"apple-m1\" \"target-features\"=\"+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+sha3,+sm4,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8a,+zcm,+zcz\" }\n", "attributes #1 = { \"frame-pointer\"=\"non-leaf\" \"no-trapping-math\"=\"true\" \"probe-stack\"=\"__chkstk_darwin\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"apple-m1\" \"target-features\"=\"+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+sha3,+sm4,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8a,+zcm,+zcz\" }\n", "\n", "!llvm.module.flags = !{!0, !1, !2, !3, !4}\n", "!llvm.ident = !{!5}\n", "\n", "!0 = !{i32 2, !\"SDK Version\", [2 x i32] [i32 14, i32 5]}\n", "!1 = !{i32 1, !\"wchar_size\", i32 4}\n", "!2 = !{i32 8, !\"PIC Level\", i32 2}\n", "!3 = !{i32 7, !\"uwtable\", i32 1}\n", "!4 = !{i32 7, !\"frame-pointer\", i32 1}\n", "!5 = !{!\"Apple clang version 15.0.0 (clang-1500.3.9.4)\"}\n", "\n", NULL }; static int creg; /* current register */ static int lreg; /* operand register */ static int xreg; /* operand register */ static int reg_sp; /* REGister Stack-Pointer */ #define MAX_MAX 20 static int regs[MAX_MAX]; /* 使われているレジスタを示すフラグ */ static int reg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ const int MAX_REGISTER=20; static int get_register() { /* 使われていないレジスタを調べる */ int i; for(i=0;i<MAX_REGISTER;i++) { if (! regs[i]) { /* 使われていないなら */ regs[i]=1; /* そのレジスタを使うことを宣言し */ return i; /* その場所を表す番号を返す */ } } return -1; /* 空いている場所がないなら、それを表す -1 を返す */ } static void free_register(int i) { /* いらなくなったレジスタを開放 */ regs[i]=0; } /* static int register_full() { int i; for(i=0;i<MAX_REGISTER;i++) { if (! regs[i]) { return 0; } } return 1; } */ void emit_init() { int i; for(i=0;i<MAX_REGISTER;i++) regs[i]=0; creg = get_register(); reg_sp = 0; } static int pop_register() { /* レジスタから値を取り出す */ int i; // j = creg; i = reg_stack[--reg_sp]; if(i<0) { return i; } else { lreg = i; regs[i]=0; return lreg; } } void emit_push() { int new_reg; new_reg = get_register(); if(new_reg<0) { /* もうレジスタがない */ printf("Compilation error: too complex expression\n"); } else { reg_stack[reg_sp++] = creg; /* push するかわりにレジスタを使う */ creg = new_reg; } } int emit_pop() { pop_register(); xreg = lreg; return xreg; } void emit_compare() { int oreg; oreg = emit_pop(); printf("\t%%%d = icmp sgt i32 %%%d %%%d\n",creg,oreg,oreg); printf("\t%%%d = zext i1 %%%d to i32\n",creg,creg); } void emit_store(int assign) { int tmp = get_register(); printf("\t%%%d = getelementptr inbounds [48 x i32]* @variable, i32 0, i64 %d\n",tmp,assign); printf("\tstore i32 %%%d i32* %%%d, align 4\n",creg,tmp); free_register(tmp); } void emit_load(int d) { int tmp = get_register(); printf("\t%%%d = getelementptr inbounds [48 x i32]* @variable, i32 0, i64 %d\n", tmp, d); printf("\t%%%d = load i32* %%%d, align 4\n", creg, tmp); free_register(tmp); } static char *opcode[] = { "", "sub nsw i32", "add nsw i32", "mul nsw i32", "sdiv i32", "", "", "", "", "sub ndw i32", "sdiv i32", }; void emit_calc(enum opcode op) { int oreg; oreg = emit_pop(); if(op==O_DIV) { printf("\t%%%d = %s %%%d, %%%d\n",creg,opcode[op],oreg,oreg); } else if(op==O_SUB) { printf("\t%%%d = %s %%%d, %%%d\n",creg,opcode[op],oreg,oreg); } else { printf("\t%%%d = %s %%%d, %%%d\n",creg,opcode[op],oreg,oreg); } } void emit_value(int d) { printf("\t%%%d = i32 %d\n",creg,d); } void emit_comment() { if (before < ptr) { putchar(';'); putchar(' '); while (before < ptr) { if(*before && *before!='\n') { putchar(*before); } before++; } putchar('\n'); } } void emit_print() { printf("\t%%call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([13 x i8]* @.str, i32 %%%d, i32 0))\n", creg); } void emit_intro() { char **iptr; for(iptr=intro;*iptr;iptr++) { printf("%s",*iptr); } } void emit_ending() { char **iptr; for(iptr=ending;*iptr;iptr++) { printf("%s",*iptr); } } /* end */