diff --git a/.cirrus.yml b/.cirrus.yml index 204a8914a1..53c8adb7de 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -19,7 +19,7 @@ arm64_task: name: Code CI / arm64-ubuntu-tcc arm_container: image: ubuntu:latest - install_script: apt-get update -y && apt-get install --quiet -y build-essential pkg-config wget git valgrind libsqlite3-dev libssl-dev libxi-dev libxcursor-dev libfreetype6-dev libxi-dev libxcursor-dev libgl-dev xfonts-75dpi xfonts-base libmysqlclient-dev libpq-dev + install_script: apt-get update -y && apt-get install --quiet -y build-essential pkg-config wget git valgrind libsqlite3-dev libssl-dev libxi-dev libxcursor-dev libfreetype6-dev libxi-dev libxcursor-dev libgl-dev xfonts-75dpi xfonts-base libmysqlclient-dev libpq-dev gcc-10-arm-linux-gnueabihf libc6-dev-armhf-cross qemu-user env: DEBIAN_FRONTEND: noninteractive VFLAGS: -cc tcc -no-retry-compilation @@ -81,3 +81,8 @@ arm64_task: ./v run examples/v_script.vsh # - name: Test v tutorials ./v tutorials/building_a_simple_web_blog_with_vweb/code/blog + + # test the arm32 version of tcc + # TODO: support something like `V_EMULATOR=qemu-arm v run file.v` so that V automatically runs all binaries under qemu + ./v -arch arm32 -cc arm-linux-gnueabihf-gcc-10 -o av cmd/v && qemu-arm -L /usr/arm-linux-gnueabihf ./av -arch arm32 -cc arm-linux-gnueabihf-gcc-10 -o av2 cmd/v && qemu-arm -L /usr/arm-linux-gnueabihf ./av2 -arch arm32 -cc arm-linux-gnueabihf-gcc-10 -o av3 cmd/v && qemu-arm -L /usr/arm-linux-gnueabihf ./av3 -arch arm32 -cc arm-linux-gnueabihf-gcc-10 -o av4 cmd/v + ./v -arch arm32 -o closure_test.c vlib/v/tests/closure_test.v && arm-linux-gnueabihf-gcc-10 -o closure_test closure_test.c && qemu-arm -L /usr/arm-linux-gnueabihf ./closure_test diff --git a/vlib/v/gen/c/cheaders.v b/vlib/v/gen/c/cheaders.v index fa8a226d1a..288a82e38e 100644 --- a/vlib/v/gen/c/cheaders.v +++ b/vlib/v/gen/c/cheaders.v @@ -58,15 +58,24 @@ static inline void __sort_ptr(uintptr_t a[], bool b[], int l) { } ' -fn arm_bytes(nargs int) string { +fn arm64_bytes(nargs int) string { // start: - // ldr x16, start-0x08 + // ldr x16, start-0x08 // ldr x, start-0x10 // br x16 bytes := '0xd0, 0xff, 0xff, 0x58, 0x6, 0xff, 0xff, 0x58, 0x00, 0x02, 0x1f, 0xd6' return bytes.replace('', nargs.str()) } +fn arm32_bytes(nargs int) string { + // start: + // ldr r9, start-0x4 + // ldr r, start-0x8 + // bx r9 + bytes := '0x0c, 0x90, 0x1f, 0xe5, 0x14, 0x0, 0x1f, 0xe5, 0x19, 0xff, 0x2f, 0xe1' + return bytes.replace('', nargs.str()) +} + // Heavily based on Chris Wellons's work // https://nullprogram.com/blog/2017/01/08/ @@ -74,7 +83,7 @@ fn c_closure_helpers(pref &pref.Preferences) string { if pref.os == .windows { verror('closures are not implemented on Windows yet') } - if pref.arch !in [.amd64, .arm64] { + if pref.arch !in [.amd64, .arm64, .arm32] { verror('closures are not implemented on this architecture yet: $pref.arch') } mut builder := strings.new_builder(2048) @@ -109,17 +118,35 @@ static unsigned char __closure_thunk[6][13] = { builder.write_string(' static unsigned char __closure_thunk[6][12] = { { - ${arm_bytes(0)} + ${arm64_bytes(0)} }, { - ${arm_bytes(1)} + ${arm64_bytes(1)} }, { - ${arm_bytes(2)} + ${arm64_bytes(2)} }, { - ${arm_bytes(3)} + ${arm64_bytes(3)} }, { - ${arm_bytes(4)} + ${arm64_bytes(4)} }, { - ${arm_bytes(5)} + ${arm64_bytes(5)} + }, +}; +') + } else if pref.arch == .arm32 { + builder.write_string(' +static unsigned char __closure_thunk[6][12] = { + { + ${arm32_bytes(0)} + }, { + ${arm32_bytes(1)} + }, { + ${arm32_bytes(2)} + }, { + ${arm32_bytes(3)} + }, { + ${arm32_bytes(4)} + }, { + ${arm32_bytes(5)} }, }; ')