diff options
| author | Daniel Glöckner <daniel-gl@gmx.net> | 2016-10-09 00:14:40 +0200 |
|---|---|---|
| committer | Daniel Glöckner <daniel-gl@gmx.net> | 2016-10-09 00:14:40 +0200 |
| commit | 78c08898aeb88ae3f8e6a775532a49712188875a (patch) | |
| tree | 7821f165f4fce36e84aabdcb4a362a31de7247f2 /arm-gen.c | |
| parent | bf10bca192ee3a0ed4e5098938dbaf3bed62dd22 (diff) | |
| download | tinycc-78c08898aeb88ae3f8e6a775532a49712188875a.tar.gz tinycc-78c08898aeb88ae3f8e6a775532a49712188875a.tar.bz2 | |
arm-gen.c: support VLAs
Diffstat (limited to 'arm-gen.c')
| -rw-r--r-- | arm-gen.c | 26 |
1 files changed, 23 insertions, 3 deletions
@@ -2122,17 +2122,37 @@ void ggoto(void) /* Save the stack pointer onto the stack and return the location of its address */ ST_FUNC void gen_vla_sp_save(int addr) { - tcc_error("variable length arrays unsupported for this target"); + SValue v; + v.type.t = VT_PTR; + v.r = VT_LOCAL | VT_LVAL; + v.c.i = addr; + store(TREG_SP, &v); } /* Restore the SP from a location on the stack */ ST_FUNC void gen_vla_sp_restore(int addr) { - tcc_error("variable length arrays unsupported for this target"); + SValue v; + v.type.t = VT_PTR; + v.r = VT_LOCAL | VT_LVAL; + v.c.i = addr; + load(TREG_SP, &v); } /* Subtract from the stack pointer, and push the resulting value onto the stack */ ST_FUNC void gen_vla_alloc(CType *type, int align) { - tcc_error("variable length arrays unsupported for this target"); + int r = intr(gv(RC_INT)); + o(0xE04D0000|(r<<12)|r); /* sub r, sp, r */ +#ifdef TCC_ARM_EABI + if (align < 8) + align = 8; +#else + if (align < 4) + align = 4; +#endif + if (align & (align - 1)) + tcc_error("alignment is not a power of 2: %i", align); + o(stuff_const(0xE3C0D000|(r<<16), align - 1)); /* bic sp, r, #align-1 */ + vpop(); } /* end of ARM code generator */ |
