summaryrefslogtreecommitdiffstats
path: root/src/register.c
diff options
context:
space:
mode:
authorTing-Wei Lan <lantw44@gmail.com>2016-01-20 06:43:17 +0800
committerTing-Wei Lan <lantw44@gmail.com>2016-01-20 06:43:17 +0800
commit46b7c22b5f3fcb33c753ec7ddceba530999283f0 (patch)
tree61aa8450fdffe017c750dbc95fce47ac078534e7 /src/register.c
parent9eebade5e06e86588a2810aa658c85bdc02b354e (diff)
downloadcompiler2015-46b7c22b5f3fcb33c753ec7ddceba530999283f0.tar
compiler2015-46b7c22b5f3fcb33c753ec7ddceba530999283f0.tar.gz
compiler2015-46b7c22b5f3fcb33c753ec7ddceba530999283f0.tar.bz2
compiler2015-46b7c22b5f3fcb33c753ec7ddceba530999283f0.tar.lz
compiler2015-46b7c22b5f3fcb33c753ec7ddceba530999283f0.tar.xz
compiler2015-46b7c22b5f3fcb33c753ec7ddceba530999283f0.tar.zst
compiler2015-46b7c22b5f3fcb33c753ec7ddceba530999283f0.zip
Support calling functions with arguments
1. The symbol attribute is modified to allow storing a related register instead of a memory location. 2. Call check_relop_expr() on all scalar function arguments to make sure that type information is available when generating code. 3. calc_array_offset() is modified to accept incomplete arrays, which is used when passing parts of arrays as arguments. 4. It is currently possible to crash the code generator by calling a function with more than 3 arguments.
Diffstat (limited to 'src/register.c')
-rw-r--r--src/register.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/src/register.c b/src/register.c
index 8ca8b6c..e7759fd 100644
--- a/src/register.c
+++ b/src/register.c
@@ -218,6 +218,30 @@ void ccmmc_register_caller_load(CcmmcRegPool *pool)
(i + 1) * REG_SIZE);
}
+void ccmmc_register_save_arguments(CcmmcRegPool *pool, int arg_count)
+{
+ if (arg_count <= 0)
+ return;
+ if (arg_count >= 8)
+ arg_count = 8;
+ for (int i = 0; i < arg_count; i++)
+ fprintf(pool->asm_output, "\tstr\tx%d, [sp, #-%d]\n",
+ i, (i + 1) * 8);
+ fprintf(pool->asm_output, "\tsub\tsp, sp, %d\n", arg_count * 8);
+}
+
+void ccmmc_register_load_arguments(CcmmcRegPool *pool, int arg_count)
+{
+ if (arg_count <= 0)
+ return;
+ if (arg_count >= 8)
+ arg_count = 8;
+ fprintf(pool->asm_output, "\tadd\tsp, sp, %d\n", arg_count * 8);
+ for (int i = 0; i < arg_count; i++)
+ fprintf(pool->asm_output, "\tldr\tx%d, [sp, #-%d]\n",
+ i, (i + 1) * 8);
+}
+
void ccmmc_register_fini(CcmmcRegPool *pool)
{
// TODO: free register pool