[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"
[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]