Skip to content

Modular arithmetic fails to compile on msp430 target. #9807

@nmichaels

Description

@nmichaels

Given the following program:

const std = @import("std");

export fn modNum(a: u8) u8 {
    return a % 14;
}

fn reset() noreturn {
    asm volatile ("mov 0, r0");
    unreachable;
}

export fn main() noreturn {
    var n: u8 = 0;
    while (n < 152) : (n += 1) {
        if (modNum(n) >= 14) {
            reset();
        }
    }
    while (true) {}
}

pub export fn _start() linksection(".init9") noreturn {
    asm volatile (
        \\ jmp main
    );
    unreachable;
}

and appropriate linker scripts from TI's Energia release (or maybe MSP430-GCC, see link below), the following command ought to build something:

zig build-exe -Lldscripts -Lldscripts/msp430g2553 --script msp430.x --single-threaded -O ReleaseSmall -target msp430-freestanding-none -mcpu msp430 modulo.zig

And if you change the % in modNum to a +, it does. (Though it won't run because there's no interrupt table and _start does none of the setup stuff it's supposed to do.) However, as is, it spits out this error:

>>> referenced by modulo.zig:4 (/home/nathan/zig/mod/modulo.zig:4)
>>>               zig-cache/o/4ed470d32b8b5d645abaefc9c97f90f7/modulo.o:(modNum)
thread 1570666 panic: attempt to unwrap error: LLDReportedFailure
/home/nathan/zig/zig/lib/std/heap.zig:147:9: 0x55949f7bf986 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/home/nathan/zig/zig/lib/std/mem/Allocator.zig:319:16: 0x55949f9f3d79 in std.mem.Allocator.resize (zig1)
    const rc = try self.resizeFn(self, old_byte_slice, Slice.alignment, new_byte_count, 0, @returnAddress());
               ^
/home/nathan/zig/zig/lib/std/os.zig:1761:19: 0x55949fabf69c in std.os.unlinkatZ (zig1)
        ENOENT => return error.FileNotFound,
                  ^
/home/nathan/zig/zig/lib/std/fs.zig:1359:25: 0x55949f997a4f in std.fs.Dir.deleteFileZ (zig1)
            else => |e| return e,
                        ^
/home/nathan/zig/zig/lib/std/fs.zig:1338:13: 0x55949f905627 in std.fs.Dir.deleteFile (zig1)
            return self.deleteFileZ(&sub_path_c);
            ^
/home/nathan/zig/zig/lib/std/heap.zig:147:9: 0x55949f7bf986 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/home/nathan/zig/zig/lib/std/mem/Allocator.zig:319:16: 0x55949f9f3d79 in std.mem.Allocator.resize (zig1)
    const rc = try self.resizeFn(self, old_byte_slice, Slice.alignment, new_byte_count, 0, @returnAddress());
               ^
/home/nathan/zig/zig/lib/std/heap.zig:147:9: 0x55949f7bf986 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/home/nathan/zig/zig/lib/std/heap.zig:147:9: 0x55949f7bf986 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/home/nathan/zig/zig/lib/std/heap.zig:147:9: 0x55949f7bf986 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/home/nathan/zig/zig/lib/std/heap.zig:147:9: 0x55949f7bf986 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/home/nathan/zig/zig/lib/std/heap.zig:147:9: 0x55949f7bf986 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/home/nathan/zig/zig/lib/std/heap.zig:147:9: 0x55949f7bf986 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/home/nathan/zig/zig/lib/std/heap.zig:147:9: 0x55949f7bf986 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/home/nathan/zig/zig/lib/std/heap.zig:147:9: 0x55949f7bf986 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/home/nathan/zig/zig/lib/std/mem/Allocator.zig:319:16: 0x55949f9f3d79 in std.mem.Allocator.resize (zig1)
    const rc = try self.resizeFn(self, old_byte_slice, Slice.alignment, new_byte_count, 0, @returnAddress());
               ^
/home/nathan/zig/zig/lib/std/heap.zig:147:9: 0x55949f7bf986 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/home/nathan/zig/zig/lib/std/heap.zig:147:9: 0x55949f7bf986 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/home/nathan/zig/zig/lib/std/mem/Allocator.zig:319:16: 0x55949f9f3d79 in std.mem.Allocator.resize (zig1)
    const rc = try self.resizeFn(self, old_byte_slice, Slice.alignment, new_byte_count, 0, @returnAddress());
               ^
/home/nathan/zig/zig/lib/std/heap/arena_allocator.zig:115:13: 0x55949f88578f in std.heap.arena_allocator.ArenaAllocator.resize (zig1)
            return error.OutOfMemory;
            ^
/home/nathan/zig/zig/lib/std/mem/Allocator.zig:319:16: 0x55949f9f3d79 in std.mem.Allocator.resize (zig1)
    const rc = try self.resizeFn(self, old_byte_slice, Slice.alignment, new_byte_count, 0, @returnAddress());
               ^
/home/nathan/zig/zig/lib/std/heap.zig:147:9: 0x55949f7bf986 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/home/nathan/zig/zig/lib/std/mem/Allocator.zig:319:16: 0x55949f9f3d79 in std.mem.Allocator.resize (zig1)
    const rc = try self.resizeFn(self, old_byte_slice, Slice.alignment, new_byte_count, 0, @returnAddress());
               ^
/home/nathan/zig/zig/lib/std/heap.zig:147:9: 0x55949f7bf986 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/home/nathan/zig/zig/lib/std/mem/Allocator.zig:319:16: 0x55949f9f3d79 in std.mem.Allocator.resize (zig1)
    const rc = try self.resizeFn(self, old_byte_slice, Slice.alignment, new_byte_count, 0, @returnAddress());
               ^
/home/nathan/zig/zig/src/link/Elf.zig:1721:21: 0x55949f961ebf in link.Elf.linkWithLLD (zig1)
                    return error.LLDReportedFailure;
                    ^
/home/nathan/zig/zig/src/link/Elf.zig:733:9: 0x55949f950c16 in link.Elf.flush (zig1)
        return self.linkWithLLD(comp);
        ^
/home/nathan/zig/zig/src/link.zig:394:21: 0x55949f90cbdd in link.File.flush (zig1)
            .elf => return @fieldParentPtr(Elf, "base", base).flush(comp),
                    ^
/home/nathan/zig/zig/src/Compilation.zig:1354:5: 0x55949f905f23 in Compilation.update (zig1)
    try self.bin_file.flush(self);
    ^
/home/nathan/zig/zig/src/main.zig:1998:5: 0x55949f89ef8d in main.updateModule (zig1)
    try comp.update();
    ^
/home/nathan/zig/zig/src/main.zig:1841:21: 0x55949f7ece18 in main.buildOutputType (zig1)
        else => |e| return e,
                    ^
/home/nathan/zig/zig/src/main.zig:162:9: 0x55949f7c3e25 in main.mainArgs (zig1)
        return buildOutputType(gpa, arena, args, .{ .build = .Exe });
        ^
???:?:?: 0x55949f7c5245 in ??? (???)
/home/nathan/zig/zig/src/stage1.zig:45:43: 0x55949f7c396d in main (zig1)
        stage2.mainArgs(gpa, arena, args) catch unreachable;
                                          ^
Aborted

I zipped up a copy of this source and the linker scripts and put it at:

https://www.nmichaels.org/files/modbug.tar.gz

It seems like __mspabi_remu is being emitted by the compiler, but it's missing from the runtime library. While we're at it, there's a large set of functions like this that ought to be in compiler-rt documented in the ABI.

LLVM's implementation:
https://github.com/llvm/llvm-project/blob/d480f968ad8b56d3ee4a6b6df5532d485b0ad01e/llvm/test/CodeGen/MSP430/libcalls.ll

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementSolving this issue will likely involve adding new logic or components to the codebase.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions