[video member=pervognsen stream_platform=twitch project=bitwise title="More Assembler Hacking" vod_platform=youtube id=_6zAlm0Edrw annotator=Miblo]
[0:00][Recap and set the stage for the day, with a mention of the pacing of the stream][:speech]
[1:58][Pull our test :asm out into a multi-line string]
[2:54][:Run it to see that it didn't work]
[3:18][Allow parse_line() to optionally match a \\n at the beginning][:parsing]
[3:46][:Run it and show the :emulation in action][:asm :parsing]
[4:05][Define other data types and helper commands in the cmd_defs table, introducing cmd_org() and cmd_align()][:asm :"code generation"]
[7:19][Test creation of a uint8][:asm :"code generation"]
[8:44][:Run it to see how the emulator handles our uint8][:asm :"code generation" :emulation]
[9:57][Introduce cmd_fill()[ref
    site="GNU Binutils"
    page="7.33 .fill repeat , size , value"
    url=https://sourceware.org/binutils/docs-2.28/as/Fill.html]][:asm :"code generation"]
[15:26][Test our fill command, enabling cmd_fill() to handle commas][:asm :"code generation"]
[17:27][:Run it and hit an "Expected instruction" error][:asm :"code generation"]
[18:07][Add fill to the cmd_defs table, and add :"error handling" to cmd_fill()][:asm :"code generation"]
[20:40][:Run it to see our fill in action][:asm :"code generation" :emulation]
[21:04][Do a test of placing a variable at a specific position using org rather than fill][:asm :"code generation"]
[22:17][:Run it to see this in action, and explain why it works][:asm :"code generation" :emulation]
[22:45][@rygorous][@pervognsen Your cmd_uint16() is buggy (it does uint8 only)][:asm :"code generation"]
[22:50][Fix cmd_uint16() to call asm_uint16()][:asm :"code generation"]
[23:04][Begin to enable parse_instr() to handle store instructions[ref
    author="Andrew Waterman and Krste Asanović"
    title="The RISC-V Instruction Set Manual - Volume 1: User-Level ISA"
    url=https://github.com/riscv/riscv-isa-manual/blob/master/release/riscv-spec-v2.2.pdf]][:asm :isa]
[24:45][Two variants of load][:asm :isa :speech]
[26:09][@rygorous][Most RISCs do have "store <value>, (<effective_addr>)" though][:isa]
[26:30][Enable parse_instr() to handle both the register- and label-based load instruction][:asm :"code generation"]
[31:05][Test a register-based load][:asm :"code generation"]
[31:59][:Run it and hit an "Immediate is out of range" error][:asm :"code generation" :emulation]
[32:55][Reduce the offset in our addi instruction][:asm]
[33:00][:Run it to see that it works][:asm :"code generation" :emulation]
[33:07][Test parenthesised offset in our lw instruction][:asm :"code generation"]
[33:13][:Run it to see that it works][:asm :"code generation" :emulation]
[33:16][Try changing that offset to our lw instruction, also editing the org instruction to match][:asm :"code generation"]
[33:23][:Run it to see that this works too][:asm :"code generation" :emulation]
[33:40][@miotatsu][I wasn't a fan of the store syntax when I first encountered it in RISC-V :asm either]
[34:18][Introduce cmd_li() adding li to the cmd_defs table][:asm :"code generation"]
[36:43][Test an li instruction][:asm :"code generation"]
[36:50][:Run it and hit an "Immediate is out of range" error][:asm :"code generation" :emulation]
[37:13][Fix cmd_li() to correctly emit our immediate][:asm :"code generation"]
[37:43][:Run it to see that li works][:asm :"code generation" :emulation]
[37:49][Enable cmd_li() to handle full-width immediates][:asm :"code generation"]
[38:41][Test loading a big immediate][:asm :"code generation"]
[39:00][:Run it to see that it works][:asm :"code generation" :emulation]
[39:48][Enable parse_instr() to handle store instructions][:asm :parsing]
[43:37][Test a sw instruction][:asm :"code generation"]
[44:34][:Run it to see that the sw instruction works][:asm :"code generation" :emulation]
[45:20][A few thoughts on x86 deference syntax][:isa :speech]
[46:50][Introduce parse_addr() for parse_instr() to call, changing our load instruction to use the '\[' and '\]' syntax][:asm :parsing]
[54:16][Test our \[ / \] syntax][:asm :parsing]
[54:31][:Run it to see that it works][:asm :emulation :parsing]
[54:38][Switch the store handling to use '\[' and '\]'][:asm :parsing]
[56:06][:Run it to see that it works][:asm :emulation :parsing]
[56:41][Further test our notation][:asm :parsing]
[57:00][:Run it to see that it works][:asm :emulation :parsing]
[57:42][Enable parse_instr() to handle the label-based store instruction][:asm :"code generation"]
[59:44][Test a label-based store][:asm :"code generation"]
[1:00:13][:Run it to see that it works][:asm :"code generation" :emulation]
[1:00:31][@rygorous][Looking SPARC-y now! Well, halfway between SPARC and ARM. (This is why MIPS has the "at" register, "assembler temporary")][:isa]
[1:01:57][Enable parse_instr() to handle branches,[ref
    author="Andrew Waterman and Krste Asanović"
    title="The RISC-V Instruction Set Manual - Volume 1: User-Level ISA"
    url=https://github.com/riscv/riscv-isa-manual/blob/master/release/riscv-spec-v2.2.pdf] introducing parse_label()][:asm :"code generation" :parsing]
[1:07:26][Enable parse_instr() to handle jump and link, introducing cmd_jmp()][:asm :"code generation" :parsing]
[1:12:27][Test branching and jumping][:asm :"code generation" :parsing]
[1:13:15][Enable scan_int() to handle negative numbers][:parsing]
[1:15:23][:Run it to see that it all works][:asm :"code generation" :emulation]
[1:16:17][Test the j instruction][:asm :"code generation"]
[1:16:41][:Run it and hit a "Jump target is out of range" error][:asm :"code generation" :emulation]
[1:18:16][Fix cmd_jump() to use the offset][:asm :"code generation"]
[1:18:23][:Run it to see that it works][:asm :"code generation" :emulation]
[1:18:30][Rewrite the :asm test to perform the check after one iteration][:"code generation"]
[1:19:53][:Run it to see that it works][:asm :"code generation" :emulation]
[1:20:25][@elavid][But you know statically that the first check will go the loop since you just loaded x1 and x2][:asm]
[1:20:42][Try an addi based on user input][:asm :"code generation" :"input handling"]
[1:23:26][:Run it to see that it works][:asm :"code generation" :emulation :"input handling"]
[1:24:47][Enable parse_instr() to handle the jalr instruction][:asm :"code generation" :parsing]
[1:28:37][Introduce cmd_jmp_reg(), cmd_call() and cmd_ret() to handle the jr, call and ret instructions[ref
    author="Andrew Waterman and Krste Asanović"
    title="The RISC-V Instruction Set Manual - Volume 1: User-Level ISA"
    url=https://github.com/riscv/riscv-isa-manual/blob/master/release/riscv-spec-v2.2.pdf]][:asm :"code generation"]
[1:34:47][@jgomes83][@pervognsen Line 985: && instead of <=]
[1:34:55][Finish implementing cmd_ret()][:asm :"code generation"]
[1:35:38][Test our call and return capabilities, doing a mul routine][:asm :"code generation"]
[1:38:49][:Run it and hit an "Expected name, got newline" error][:asm :"code generation"]
[1:40:05][Remove a comment from our test :asm]
[1:40:11][:Run it to determine that there's a lexer bug in comment :parsing]
[1:40:20][Test multiplication of user-input values][:asm :"code generation"]
[1:41:39][:Run it and try our user-input multiplication][:asm :"code generation" :emulation :"input handling"]
[1:44:49][Enable parse_instr() to handle lui (load upper immediate)][:asm :"code generation"]
[1:45:32][:Run it to see that it works][:asm :"code generation" :emulation]
[1:46:14][Q&A][:speech]
[1:46:49][Reflect on our assembler, with a glimpse into the future of supporting constant expressions and local labels][:asm :speech]
[1:51:32][That's it for today][:speech]
[/video]
