1. Branch Instructions (B-Type)

  • Purpose: conditional PC updates based on register comparisons
  • Formats recap:
    | imm[12] imm[10:5] rs2 rs1 funct3 imm[4:1] imm[11] opcode |
  • Common opcodes:
    • beq (000): branch if equal
    • bne (001): branch if not equal
    • blt (100): branch if less than (signed)
    • bge (101): branch if greater or equal (signed)
    • bltu/bgeu: unsigned variants
  • Target calculation:
  • Sign-extension: assemble imm bits then extend bit 12 across upper bits

2. Jumps (J- and I-Type)

2.1 JAL (J-Type)

  • Opcode: 1101111
  • Format:
    | imm[20] imm[10:1] imm[11] imm[19:12] rd opcode |
  • Operation:
    jal rd, offset
    • rd ← PC + 4
    • PC ← PC + SE(offset_20|19:12|11|10:1|0)

2.2 JALR (I-Type)

  • Opcode: 1100111, funct3 = 000
  • Format: I-Type
  • Operation:
    jalr rd, rs1, imm
    • rd ← PC + 4
    • PC ← (rs1 + SE(imm)) & ~1
    • clears LSB for alignment

3. Function Call/Return Conventions

  • Call: jal ra, label or jal x1, label
  • Return: jalr x0, ra, 0 (jump to return address register)
  • Stack usage:
    • Save caller-saved registers onto stack
    • Adjust sp in prologue/epilogue
  • Example prologue/epilogue:
    addi sp, sp, -16      # allocate stack frame
    sw   ra, 12(sp)
    sw   s0, 8(sp)
    addi s0, sp, 16       # set frame pointer
    ...                   # function body
    lw   ra, 12(sp)
    lw   s0, 8(sp)
    addi sp, sp, 16       # deallocate
    jalr x0, ra, 0        # return

4. Addressing Modes

  • Register-immediate (base): ld/st rs1 + imm
  • PC-relative: used by auipc, jal, beq offsets
  • Immediate only: U-Type for lui loads high bits
  • Memory-aligned offsets: offsets in bytes, must align to data width
  • Examples:
    • lw x5, 4(x10) → x5 ← M[x10 + 4]
    • sw x6, -8(x2) → M[x2 – 8] ← x6

5. Linking Branches & Jumps

  • Static labels: assembler computes offsets
  • PC-relative pros: position-independent code
  • Hazards: control hazards in pipelines (Lecture 8)