MIPS Programmer's Handbook - Errata

Updated 98-05-02.

This is a list of the known problems with our book. If you find anything else, we would be happy to add it to this list, so that everyone else can benefit from your vigilance.

We had enormous problems with the '~' character. It seems to have been deleted during some step in the book production process. This means that the one's complement operator '~' needs to be added in many places. For example,

	        and        t0,SR_IEC

becomes

                and        t0,~SR_IEC

Here are the cases that have been discovered so far:

Page 28 code line 100
Page 30 code line 75
Page 32 code line 9
Page 38 code line 75
Page 39 code line 100
Page 40 code line 9
Page 41 code line 46
Page 65 code line 124
Pages 396, 397, 398, and 399

Page 9, Section 2.3. Comment for sw instruction should read:

	 # store ra into sp+20

Page 12. Line 2 should read:

"... for a size of 24 bytes and"

Page 13. Third paragraph should read:

"... is given in Appendix C. ..."

Page 13, Section 2.5.1. First Paragraph should end with:

"It returns the length in register v0."

Page 15. Line 1 should read:

	.frame sp,24,ra

Page 15, Section 2.5.4. The example code contains several errors, it should read:

        .globl f4
        .ent f4
f4:     # nonleaf function that uses 3 save registers
        .mask   0x80070000,-4
        .frame sp,32,ra
        subu    sp,(4+4)*4      # a0..a3 s0..s2
        sw      ra,7*4(sp)      # store ra on the stack at sp+28
        sw      s2,6*4(sp)
        sw      s1,5*4(sp)
        sw      s0,4*4(sp)
        # incoming args: a0..a3 & (4+(4+4))*4(sp)..
        # registers available: t0..t9 s0..s1
        move    s0,a0
        move    s1,a1
1:      lw      a0,(s0)
        beq     a0,zero,1f
        jal     f1 
        move    a0,s1
        lw      a1,(s0)
        move    a2,v0
        jal     printf
        addu    s0,4
        b       1b              # branch back to 1:
1:      # no return value
        # return values: v0..v1
     	lw      s0,4*4(sp)
     	lw      s1,5*4(sp)
     	lw      s2,6*4(sp)
     	lw      ra,7*4(sp)
     	addu    sp,(4+4)*4
     	j       ra
     	.end f4
Page 16, Section 2.5.5. The mask directive in the example code should use the value 0x800f0000, not 0x80f00000.

Page 17, Section 2.5.6. The add.d in the example code should not be commented out.

Page 23, Section 3.2.2. Last line of the page. Should read,

	lw	t0,(t0)

Page 28. Second paragraph should read:

To handle the unlikely case that the marker is already on one of the cache boundaries, we clear the word just beyond the last address in each of the possible cache sizes.

Page 76. The declaration for 'ticks' on line 1 needs the directive 'volatile' to protect it from overenthusiastic optimizers. The code should read:

    1	   volatile int ticks;
Page 79. The function 'handler' is missing a ".set noat" directive. The code should read:

  104	        .ent handler
	        .set noat
  105	handler:
Page 89. The code on line 145 is wrong. It should read:

  145  1:  #spurious interrupt, ...
  146      #....
	   .set noreorder
	   mfc0	k0,C0_EPC
	   nop
	   .set reorder
  147      b done
Page 97. The code on line 237 permits the possiblity that the return address placed in k0 on line 239 could be overwritten if an interrupt occurs within the 3 cycles that it takes for the CPU to disable interrupts after the mfc0 instruction on line 236. The code should read:

  234  		lw	t0,C0_SR*4(sp)
  235  		nop
  236  		mtc0 	t0,C0_SR
		nop
  237  		.set reorder
  238		lw	t0,C_T0*4(sp)
  239		lw	k0,C_EPC*4(sp
Page 128. The store-word instruction on line 177 saves the wrong register. It should read:

  177        sw    v1,E_V1*4(sp)
Page 135. The shift instruction on line 494 uses the wrong shift amount. It should read:

  494        sll   t0,t3,31-27
Page 322. The desciption of the .frame directive is wrong. Line 6 of the first paragraph should read:

"... is used with three parameters:..."

The last line of that paragraph should read:

"... stack size of 24 bytes and the ..."

Page 330. The code example has an AND instead of an OR, it should read:

	mfc0	t0,C0_SR
	nop
	or	t0,SR_CU1
	mtc0	t0,C0_SR
	nop
	nop
	ctc1	t1,C1_FCR
Page 331. The reference to copn should be cn.

Page 334. The text in the figure illustrating the format of $f11 for single-precision floating-point is wrong. It should read "Not Used".

Page 356. Table B.1 should read:


Operand Meaning
Gpr CPU general register Fpre Floating-point general register, even Cpr Coprocessor general register Imm2 Immediate value, power of 2 Imm16 16-bit immediate value Imm16r 16-bit immediate value relative to Gpr Imm32z 32-bit immediate value, lower 16 bits = 0 Imm32 32-bit immediate value Immfp Floating-point immediate value Tlabel Text (code) label, address in .text section Dlabel Data label, address in .data section Slabel Short data label, address in .sdata section, gp-relative
Page 371. genproc.c line 58

		if (i == 0) mask <<= 7;
becomes
		if (i == 0) mask <<= 7+(9-regs);