• Chapter 2, Table 2-6 (e-book only). In some versions of the e-book, the movq instruction in the second row of Table 2-6 contains a stray {@}. It’s printed as:

    movq    {@}%rsp, %rbp
    

    But should be:

    movq    %rsp, %rbp
    
  • Chapter 6, p. 121. In the first sentence of the Parsing Conditional Expressions subsection, the ? : operator is backwards. This sentence should read:

    The conditional ? : operator is a ternary operator…

  • Chapter 13, p. 335. The assembly code given in Table 13-3 to convert from double to unsigned long includes an unnecessary instruction. As the last step in the conversion, this code copies the immediate 9223372036854775808 into a register, then adds it to the destination:

    Mov(Quadword, Imm(9223372036854775808), Reg(<R>))
    Binary(Add, Quadword, Reg(<R>), dst)
    

    This step takes two instructions because the source operand of add can’t be bigger than INT_MAX. However, it’s better to generate a single invalid add instruction at this stage and let the instruction fix-up pass rewrite it. That is, instead of those two instructions, we can just generate:

    Binary(Add, Quadword, Imm(9223372036854775808), dst)
    

    This is better because it uses one of our scratch registers (R10) instead of a non-scratch register, which will reduce register pressure once we implement register allocation in Chapter 20.

    Thanks to Yoshi Sono for catching this!

  • Chapter 20, p. 665-666. The coalesce function, discussed on pages 665-666, needs to handle an additional edge case if you completed Part II. You should not coalesce two pseudoregisters of different sizes (e.g. don’t coalesce a Longword into a Quadword or vice versa). If we coalesce a larger pseudoregister into a smaller one, and we end up spilling the coalesced register, we won’t allocate enough stack space for it, resulting in a potential miscompilation. Normally, the Briggs test should prevent the coalesced register from spilling, but the “ugly detail about the George test” discussed on page 661 means this isn’t guaranteed. Besides, as that discussion on page 661 points out, the Briggs and George tests are performance heuristics and we shouldn’t rely on them for correctness.

    Alternatively, you could coalesce pseudoregisters of different sizes but make sure to coalesce the smaller one into the larger one; however, that’s more fragile, so I don’t recommend it.