CPW Part 15: Code Generation for Jump Instructions
Exercise
For unsigned integers support for conditional jumps ordered relations (See Session 5, Page 3):
-
Extend the enumerated constants as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// supported instruction enum GenOp { GEN_CONDJMP_BEGIN, GEN_EQUAL = GEN_CONDJMP_BEGIN, GEN_NOT_EQUAL, GEN_ABOVE, GEN_ABOVE_EQUAL, GEN_BELOW, GEN_BELOW_EQUAL, GEN_CONDJMP_END, // ... };
-
This is our current instruction set:
RRR (OP u 8) (X u 8) (Y u 8) (Z u 8) RSR (OP u 8) (X u 8) (Y s 8) (Z u 8) J26 (OP u 8) (XYZ j 24) U16R (OP u 8) (XY u 16) (Z u 8) J18R (OP u 8) (XY j 16) (Z u 8) 0x01 RRR : halt %X ulm_halt(ulm_regVal(X)); 0x02 RRR : getc %X ulm_setReg(ulm_readChar() & 0xFF, X); 0x03 RRR : putc %X ulm_printChar(ulm_regVal(X) & 0xFF); 0x04 J26 : jmp XYZ ulm_unconditionalRelJump(XYZ); 0x05 RRR : subq X, %Y, %Z ulm_sub64(X, ulm_regVal(Y), Z); 0x06 J26 : jnz XYZ : jne XYZ ulm_conditionalRelJump(ulm_statusReg[ULM_ZF] == 0, XYZ); 0x07 J26 : jz XYZ : je XYZ ulm_conditionalRelJump(ulm_statusReg[ULM_ZF] == 1, XYZ); 0x08 U16R : ldzwq XY, %Z ulm_setReg(XY, Z); 0x09 RSR : movzbq Y(%X), %Z : movzbq (%X), %Z ulm_fetch64(Y, X, 0, 0, ULM_ZERO_EXT, 1, Z); 0x0A RRR : addq X, %Y, %Z ulm_add64(X, ulm_regVal(Y), Z); 0x0B RRR : imulq %X, %Y, %Z ulm_mul64(ulm_regVal(X), ulm_regVal(Y), Z); 0x0C J26 : ja XYZ ulm_conditionalRelJump(ulm_statusReg[ULM_ZF] == 0 && ulm_statusReg[ULM_CF] == 0, XYZ); 0x0D J26 : jb XYZ ulm_conditionalRelJump(ulm_statusReg[ULM_CF] == 1, XYZ); 0x0E RRR : addq %X, %Y, %Z : movq %X, %Z ulm_add64(ulm_regVal(X), ulm_regVal(Y), Z); 0x0F RRR : imulq X, %Y, %Z ulm_mul64(X, ulm_regVal(Y), Z); 0x10 RRR # Uses the 128-bit unsigned integer divider. The 64-bits stored in %Y are # therefore zero extended with %0 to 128 bits and then used as numerator. # The immediate value X is used as unsigned denominator. # # The result of the operation is the quotient and the remainder. These results # will be stored in a register pair: The quotient is stored in %Z and the # remainder in %{Z + 1}. : divq X, %Y, %Z ulm_div128(X, ulm_regVal(Y), ulm_regVal(0), Z, 0, Z + 1); 0x11 RSR # The least significant byte in %X gets stored at address %Z. : movb %X, Y(%Z) : movb %X, (%Z) ulm_store64(Y, Z, 0, 0, 1, X); 0x12 RSR # Fetches a quad word from address %X into register %Z : movq Y(%X), %Z : movq (%X), %Z ulm_fetch64(Y, X, 0, 0, ULM_ZERO_EXT, 8, Z); 0x13 RRR : putc X ulm_printChar(X & 0xFF); # void ulm_absJump(uint64_t destAddr, ulm_Reg ret); 0x14 RRR : jmp %X, %Y : call %X, %Y : ret %X ulm_absJump(ulm_regVal(X), Y); 0x15 U16R : shldwq XY, %Z ulm_setReg(ulm_regVal(Z) << 16 | XY, Z); 0x16 J18R : ldpa XY, %Z ulm_setReg(ulm_ipVal() + XY, Z); 0x17 RRR : ldfp Y(%X), %Z : ldfp (%X), %Z ulm_fetch64(Y * 8, X, 0, 0, ULM_ZERO_EXT, 8, Z); 0x18 RRR : subq %X, %Y, %Z ulm_sub64(ulm_regVal(X), ulm_regVal(Y), Z); 0x19 RSR : movq %X, Y(%Z) : movq %X, (%Z) ulm_store64(Y, Z, 0, 0, 8, X); 0x1A RRR # Uses the 128-bit unsigned integer divider. The 64-bits stored in %Y are # therefore zero extended with %0 to 128 bits and then used as numerator. # The value %X is used as unsigned denominator. # # The result of the operation is the quotient and the remainder. These results # will be stored in a register pair: The quotient is stored in %Z and the # remainder in %{Z + 1}. : divq %X, %Y, %Z ulm_div128(ulm_regVal(X), ulm_regVal(Y), ulm_regVal(0), Z, 0, Z + 1); # General meaning of the mnemonics @addq # Integer addition. @getc # Get character @divq # 64-bit unsigned integer division @halt # Halt program @imulq # 64-bit unsigned and signed integer multiplication. @ja # Jump if above (conditional jump). @jb # Jump if below (conditional jump). @je # Jump if equal (conditional jump). @jmp # Jump (unconditional jump). @jne # Jump if not equal (conditional jump). @jnz # Jump if not zero (conditional jump). @jz # Jump if zero (conditional jump). @ldzwq # Load zero extended word to quad word register. @putc # Put character @subq # Integer subtraction. @movb # Move a byte from a register to memory (store instruction). @movzbq # Move zero extended byte to quad word register (fetch instruction). @movq # Move quad word @shldwq # Shift (destination register) and load word @ldpa # Load Pool Address @ldfp # Load from Pool
Extend it for two conditional jump instructions jae (jump above equal) and jbe (jump below equal).
Update
In the original isa.txt the instruction divq where all operands are registers was missing.
-
Adapt the implementation of genCondJmp().
-
Extend the test for the code generation interface before you proceed.