Skip to content

Stage2 riscv64 support #5984

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed

Conversation

pfgithub
Copy link
Contributor

@pfgithub pfgithub commented Aug 4, 2020

export fn _start() noreturn {
    print();
    exit();
}
fn print() void {
    asm volatile ("ecall"
        :
        : [sys] "{a7}" (64),
          [arg1] "{a0}" (1),
          [arg2] "{a1}" (@ptrToInt("Hello, World!\n")),
          [arg3] "{a2}" ("Hello, World!\n".len)
        : "memory"
    );
}
fn exit() noreturn {
    asm volatile ("ecall"
        :
        : [sys] "{a7}" (94),
          [arg1] "{a0}" (0)
        : "memory"
    );
    unreachable;
}

({x0}{x31} also work as register names)

Still need to do:

  • save and reload ra in functions
  • align all instructions to 2 bytes
  • a test

notes for anyone else making a backend

riscv64-linux-gnu-objdump --disassembler-options=no-aliases -d testrisc
qemu-riscv64 -g 1234 testrisc
riscv64-linux-gnu-gdb -iex "target remote localhost:1234" -iex "layout asm" -iex "layout regs" testrisc
`ni` to run one instruction

@FireFox317
Copy link
Contributor

Are you sure all these packed structs work as intented? We have bugs with packed structs in stage1 atm. related #3133 #2627

@pfgithub
Copy link
Contributor Author

pfgithub commented Aug 4, 2020

@FireFox317 I didn't expect them to be working properly, but they seem to be working and are the correct size. This outputs correctly on at least x86_64 and i386 and mipsel and aarch64:

pub fn main() !void {
    const Stru = packed struct {
        opcode: u7,
        rd: u5,
        unused: u3 = 0,
        rsi1: u5,
        imm11: u11,
        signextend: u1 = 0,
    };
    @import("std").debug.warn("{b:0>32}\n", .{@intCast(u32, 0b01100000000100001000000010000001)});
    @import("std").debug.warn("{b:0>32}\n", .{@bitCast(u32, Stru{ .imm11 = 0b11000000001, .rsi1 = 1, .rd = 1, .opcode = 1 })});
}

Copy link
Member

@andrewrk andrewrk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This all looks good. Should be pretty simple to slap a compare_output test case on there and then I think it's merge ready.

Comment on lines 1509 to 1512
switch (reg.size()) {
64 => return self.genSetReg(src, reg, .{ .immediate = 0xaaaaaaaaaaaaaaaa }),
else => unreachable,
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for this switch right? If all registers are always 64 bits.

@pixelherodev
Copy link
Contributor

pixelherodev commented Aug 4, 2020 via email

@andrewrk
Copy link
Member

andrewrk commented Aug 4, 2020

I'll make a change in master branch regarding the to64 things that should clear up how to (not have to) do it for other architectures

@pfgithub pfgithub marked this pull request as ready for review August 4, 2020 21:32
@andrewrk
Copy link
Member

andrewrk commented Aug 4, 2020

Nice work! Merged in e4eb439. In that branch before merging I also made -Denable-qemu work.

...actually I forgot to check that the test was working, looks like it's not failing when I mangle the "hello world" text. Will push a follow-up commit shortly. But anyway the code is merged into master.

@andrewrk andrewrk closed this Aug 4, 2020
@andrewrk
Copy link
Member

andrewrk commented Aug 4, 2020

Fixed in d61a9e3:

Test [1/1] test "self-hosted"...tests [1/19] call undefined local [1/1] update [2/3] parse/analysis/codtests [7/19] hello world [1/1] update [4/4] update index 0, mismatched stdout
====Expected (len=14):====
Hello, World!

====Actual (len=14):====
Hello2, World!
========

/home/andy/dev/zig/src-self-hosted/test.zig:650:40: 0x28042b in TestContext.runOneCase (test)
                        std.debug.panic(
                                       ^
/home/andy/dev/zig/src-self-hosted/test.zig:421:32: 0x27b1df in TestContext.run (test)
            try self.runOneCase(std.testing.allocator, &prg_node, case);
                               ^
/home/andy/dev/zig/src-self-hosted/test.zig:21:16: 0x27ad25 in test "self-hosted" (test)
    try ctx.run();
               ^
/home/andy/dev/zig/lib/std/special/test_runner.zig:48:28: 0x4a1f25 in std.special.main (test)
        } else test_fn.func();
                           ^
/home/andy/dev/zig/lib/std/start.zig:252:37: 0x27b8bd in std.start.posixCallMainAndExit (test)
            const result = root.main() catch |err| {
                                    ^
/home/andy/dev/zig/lib/std/start.zig:123:5: 0x27b5ff in std.start._start (test)
    @call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{});
    ^

Tests failed. Use the following command to reproduce the failure:
/home/andy/dev/zig/zig-cache/o/72BKgrzz0IQ1aLeRaOFoFJ2h6DfavwqGEtek3FNxRhMTbh4kyBjTG4V7SQ2nFC0Y/test
The following command exited with error code 255:
/home/andy/dev/zig/build-release/zig test /home/andy/dev/zig/src-self-hosted/test.zig --pkg-begin build_options /home/andy/dev/zig/zig-cache/test_build_options.zig --pkg-end --cache-dir /home/andy/dev/zig/zig-cache --name test --pkg-begin stage2_tests /home/andy/dev/zig/test/stage2/test.zig --pkg-end 

Build failed. The following command failed:
/home/andy/dev/zig/zig-cache/o/Vir_I3dkRZtyxYXk0CWGKRTdft2RMrYfZnRBu3welLglJILnaN2Sv46SMzG_Sd9M/build /home/andy/dev/zig/build-release/zig /home/andy/dev/zig /home/andy/dev/zig/zig-cache test-stage2 -Denable-qemu

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants