[video member=pervognsen stream_platform=twitch project=bitwise title="RISC-V Dynamic Assembler" vod_platform=youtube id=dmrhbzq3SNg annotator=Miblo]
[0:08][Recap and set the stage for the day][:speech]
[1:38][Review the new bits() function to replace the old ad hoc bit manipulation[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]][:isa :research]
[7:56][Review step() with a note that the encoding and decoding of instructions are performed separately][:isa :research]
[9:35][Review encode_instruction() with a few words on software vs hardware decoding[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]][:isa :research]
[16:11][A few words on the benefit of writing the encoder and decoder independently][:isa :speech]
[16:59][Review the test code for the encoder and decoder][:isa :research]
[21:49][Review the test code for the simulator][:isa :research]
[22:42][:Run the simulator][:isa]
[23:24][Setup to start writing the main assembler][:isa :speech]
[24:59][Q&A][:speech]
[25:29][@nxsy][Hyper-relevant question: Why Hart?][:isa]
[26:26][Static assembler][:asm :speech]
[28:45][@rygorous][Am I the only one who hears that weird audio interference thing?]
[29:41][Static assembler, continued][:asm :speech]
[30:53][Dynamic assembler][:asm :speech]
[35:35][Data labels[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 :speech]
[40:38][Instruction labels[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 :speech]
[43:50][Handling of instruction labels by static vs dynamic assemblers][:asm :speech]
[47:58][Multi-pass vs back-patching assembling][:asm :speech]
[49:57][Q&A][:speech]
[50:18][@dghelneshi][I imagine this is very difficult for variable length encodings since you can't know where the labels are without encoding the instructions which you can't encode (optimally) without knowing how far away the label is][:asm]
[51:42][@rygorous][You don't need to do a full pass][:asm]
[52:28][Dive into writing our back-patching dynamic assembler, introducing Asm struct and def_byte(), def_half(), def_word(), def_bytes(), def_str() and check_overflow()][:asm]
[1:02:51][Introduce Reg enum, using uint8 as the storage type][:asm]
[1:05:12][Introduce emit_instr() and emission functions for add(), addi() and slli(), renaming the previous def_ functions to emit_*][:asm]
[1:10:44][Introduce init_asm() and test our assembler][:asm]
[1:12:47][:Run it to see that it works][:asm]
[1:13:10][Create instruction labels, introducing new_sym(), set_sym_here(), new_sym_here() and related structs][:asm]
[1:29:43][Introduce emit_lw() to emit a load global instruction, and emit_auipc() and emit_lw_reg()[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]
[1:36:11][Test our label emission, also introducing get_sym_addr() for emit_lw() to call][:asm]
[1:39:34][Step through new_sym() to see what it produces, and that we may not be sign-extending correctly][:asm :run]
[1:44:58][Conditional sign-extension of immediates][:asm :speech]
[1:49:02][Introduce imm_hi() and imm_lo(), and make emit_lw() use imm_lo() in its call to emit_lw_reg()][:asm]
[1:51:25][:Run it to see that it works][:asm]
[1:52:23][Q&A][:speech]
[1:52:36][@miotatsu][@pervognsen ((VALUE + 0x800) & HI20_MASK >> 12) & LO20_MASK, I don't think & with HI20_MASK is actually necessary(?) but I believe the LO20_MASK would handle the >> 12 doing an arithmetic right shift if the high bits ended up set]
[1:52:52][Change imm_hi() to straight up return imm + 0x800][:asm]
[1:53:20][:Run it to see that this works, and explain why][:asm]
[1:55:48][Try doing a load of emit_uint32() to test this imm_hi()][:asm]
[1:56:12][:Run it to see that this doesn't work][:asm]
[1:56:28][Revert imm_hi() to the old bit-shifting version][:asm]
[1:57:17][:Run it to see the same buggy result][:asm]
[1:57:58][Try emitting fewer instructions, to try and determine where it breaks][:asm :programming :run]
[1:59:28][@binjimin][The sign-extension of the 12-bit immediate either produces 0 or -1 in the top 20 bits, so you need to add 0 or 1 to the top bits to counteract it][:asm]
[2:00:08][Scour the code for the culprit][:asm]
[2:01:11][Make imm_hi() return imm + 0x800][:asm]
[2:02:09][Step in to emit_lw() and spot that the addr was at the max capacity of our RAM]
[2:02:50][Add more RAM][:asm :memory]
[2:03:18][:Run it to see that this totally works][:asm]
[2:04:10][Make check_overflow() assert on a bounds-checking failure][:memory]
[2:04:18][:Run it with a smaller amount of RAM, and hit that assertion][:asm :memory]
[2:04:39][Cut over to the extra stream][:speech]
[/video]
