m_genesis.kv 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
m_genesis.kv 2 ;; ;;
m_genesis.kv 3 ;; This file is part of 'M', a MIPS system emulator. ;;
m_genesis.kv 4 ;; ;;
m_genesis.kv 5 ;; (C) 2019 Stanislav Datskovskiy ( www.loper-os.org ) ;;
m_genesis.kv 6 ;; http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html ;;
m_genesis.kv 7 ;; ;;
m_genesis.kv 8 ;; You do not have, nor can you ever acquire the right to use, copy or ;;
m_genesis.kv 9 ;; distribute this software ; Should you use this software for any purpose, ;;
m_genesis.kv 10 ;; or copy and distribute it to anyone or in any manner, you are breaking ;;
m_genesis.kv 11 ;; the laws of whatever soi-disant jurisdiction, and you promise to ;;
m_genesis.kv 12 ;; continue doing so for the indefinite future. In any case, please ;;
m_genesis.kv 13 ;; always : read and understand any software ; verify any PGP signatures ;;
m_genesis.kv 14 ;; that you use - for any purpose. ;;
m_genesis.kv 15 ;; ;;
m_genesis.kv 16 ;; See also http://trilema.com/2015/a-new-software-licensing-paradigm . ;;
m_genesis.kv 17 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
m_genesis.kv 18
m_genesis.kv 19 ;-----------------------------------------------------------------------------
m_genesis.kv 20 section .rodata
m_genesis.kv 21 align GRAIN, db 0x90
m_genesis.kv 22 _B_Table:
m_genesis.kv 23 A32 _b_bltz ; 0x00 : bltz (000001?????00000????????????????)
m_genesis.kv 24 A32 _b_bgez ; 0x01 : bgez (000001?????00001????????????????)
m_genesis.kv 25 A32 _b_bltzl ; 0x02 : bltzl (000001?????00010????????????????)
m_genesis.kv 26 A32 _b_bgezl ; 0x03 : bgezl (000001?????00011????????????????)
m_genesis.kv 27 A32 _bad ; 0x04 : UNDEFINED
m_genesis.kv 28 A32 _bad ; 0x05 : UNDEFINED
m_genesis.kv 29 A32 _bad ; 0x06 : UNDEFINED
m_genesis.kv 30 A32 _bad ; 0x07 : UNDEFINED
m_genesis.kv 31 A32 _bad ; 0x08 : UNDEFINED
m_genesis.kv 32 A32 _bad ; 0x09 : UNDEFINED
m_genesis.kv 33 A32 _bad ; 0x0a : UNDEFINED
m_genesis.kv 34 A32 _bad ; 0x0b : UNDEFINED
m_genesis.kv 35 A32 _bad ; 0x0c : UNDEFINED
m_genesis.kv 36 A32 _bad ; 0x0d : UNDEFINED
m_genesis.kv 37 A32 _bad ; 0x0e : UNDEFINED
m_genesis.kv 38 A32 _bad ; 0x0f : UNDEFINED
m_genesis.kv 39 A32 _b_bltzal ; 0x10 : bltzal (000001????x10000????????????????)
m_genesis.kv 40 A32 _b_bgezal ; 0x11 : bgezal (000001????x10001????????????????)
m_genesis.kv 41 A32 _bad ; 0x12 : UNDEFINED
m_genesis.kv 42 A32 _bad ; 0x13 : UNDEFINED
m_genesis.kv 43 A32 _bad ; 0x14 : UNDEFINED
m_genesis.kv 44 A32 _bad ; 0x15 : UNDEFINED
m_genesis.kv 45 A32 _bad ; 0x16 : UNDEFINED
m_genesis.kv 46 A32 _bad ; 0x17 : UNDEFINED
m_genesis.kv 47 A32 _bad ; 0x18 : UNDEFINED
m_genesis.kv 48 A32 _bad ; 0x19 : UNDEFINED
m_genesis.kv 49 A32 _bad ; 0x1a : UNDEFINED
m_genesis.kv 50 A32 _bad ; 0x1b : UNDEFINED
m_genesis.kv 51 A32 _bad ; 0x1c : UNDEFINED
m_genesis.kv 52 A32 _bad ; 0x1d : UNDEFINED
m_genesis.kv 53 A32 _bad ; 0x1e : UNDEFINED
m_genesis.kv 54 A32 _bad ; 0x1f : UNDEFINED
m_genesis.kv 55 ;-----------------------------------------------------------------------------
m_genesis.kv 56
m_genesis.kv 57 section .text
m_genesis.kv 58
m_genesis.kv 59 ;-----------------------------------------------------------------------------
m_genesis.kv 60 ; B-Type Instructions :
m_genesis.kv 61 ;-----------------------------------------------------------------------------
m_genesis.kv 62
m_genesis.kv 63 ;-----------------------------------------------------------------------------
m_genesis.kv 64 ; BLTZ -- Branch on less than zero.
m_genesis.kv 65 ; Branches if the register is less than zero
m_genesis.kv 66 ; Operation: if $s < 0 advance_pc(offset << 2)); else advance_pc(4);
m_genesis.kv 67 ; Syntax: bltz $s, offset
m_genesis.kv 68 ; Encoding: 0000 01ss sss0 0000 iiii iiii iiii iiii
m_genesis.kv 69 ;-----------------------------------------------------------------------------
m_genesis.kv 70 align GRAIN, db 0x90
m_genesis.kv 71 _b_bltz:
m_genesis.kv 72 IType_I_S_Only ; load rS and Imm Fields
m_genesis.kv 73 mov nPC, PC ; nPC := PC
m_genesis.kv 74 add nPC, 0x4 ; nPC := nPC + 4
m_genesis.kv 75 SX18_4N Imm ; Sign Extend Imm * 4
m_genesis.kv 76 mov TMP, 0x4 ; TMP := 4
m_genesis.kv 77 cmp R(rS), 0 ; If Regs[rS] < 0:
m_genesis.kv 78 cmovl TMP, Imm ; ... then TMP := Imm
m_genesis.kv 79 add nPC, TMP ; nPC := nPC + TMP
m_genesis.kv 80 Flg_On InDelaySlot ; Set 'Delay Slot' Flag.
m_genesis.kv 81 jmp _end_cycle
m_genesis.kv 82 ;-----------------------------------------------------------------------------
m_genesis.kv 83
m_genesis.kv 84 ;-----------------------------------------------------------------------------
m_genesis.kv 85 ; BGEZ -- Branch on greater than or equal to zero.
m_genesis.kv 86 ; Branches if the register is greater than or equal to zero
m_genesis.kv 87 ; Operation: if $s >= 0 advance_pc(offset << 2)); else advance_pc(4);
m_genesis.kv 88 ; Syntax: bgez $s, offset
m_genesis.kv 89 ; Encoding: 0000 01ss sss0 0001 iiii iiii iiii iiii
m_genesis.kv 90 ;-----------------------------------------------------------------------------
m_genesis.kv 91 align GRAIN, db 0x90
m_genesis.kv 92 _b_bgez:
m_genesis.kv 93 IType_I_S_Only ; load rS and Imm Fields
m_genesis.kv 94 mov nPC, PC ; nPC := PC
m_genesis.kv 95 add nPC, 0x4 ; nPC := nPC + 4
m_genesis.kv 96 SX18_4N Imm ; Sign Extend Imm * 4
m_genesis.kv 97 mov TMP, 0x4 ; TMP := 4
m_genesis.kv 98 cmp R(rS), 0 ; If Regs[rS] >= 0:
m_genesis.kv 99 cmovge TMP, Imm ; ... then TMP := Imm
m_genesis.kv 100 add nPC, TMP ; nPC := nPC + TMP
m_genesis.kv 101 Flg_On InDelaySlot ; Set 'Delay Slot' Flag.
m_genesis.kv 102 jmp _end_cycle
m_genesis.kv 103 ;-----------------------------------------------------------------------------
m_genesis.kv 104
m_genesis.kv 105 ;-----------------------------------------------------------------------------
m_genesis.kv 106 ; BLTZL - Branch on Less Than Zero Likely.
m_genesis.kv 107 ; Test a register, then do a PC-relative conditional branch;
m_genesis.kv 108 ; execute the delay slot only if the branch is taken.
m_genesis.kv 109 ; An 18-bit signed offset (the 16-bit offset field shifted left 2 bits) is
m_genesis.kv 110 ; added to the address of the instruction following the branch (not the branch
m_genesis.kv 111 ; itself), in the branch delay slot, to form a PC-relative effective target
m_genesis.kv 112 ; address. If the contents of rS are less than zero (sign bit is 1), branch to
m_genesis.kv 113 ; the effective target address after the instruction in the delay slot is
m_genesis.kv 114 ; executed. If the branch is not taken, the instruction in the delay slot is
m_genesis.kv 115 ; not executed.
m_genesis.kv 116 ; Operation: if rS < 0 then PC = PC + sign_extend(offset)
m_genesis.kv 117 ; else: nullify_current_instruction
m_genesis.kv 118 ; Syntax: bltzl $s, offset
m_genesis.kv 119 ; Encoding: 0000 01ss sss0 0010 iiii iiii iiii iiii
m_genesis.kv 120 ;-----------------------------------------------------------------------------
m_genesis.kv 121 align GRAIN, db 0x90
m_genesis.kv 122 _b_bltzl:
m_genesis.kv 123 IType_S_Only ; load only rS Field just now
m_genesis.kv 124 cmp R(rS), 0 ; CMP(Regs[rS], 0)
m_genesis.kv 125 jnl _i_bltzl_not_taken ; If !(Regs[rS] < 0) then NotTaken
m_genesis.kv 126 ; Taken:
m_genesis.kv 127 IType_I_Only ; load only Imm Field just now
m_genesis.kv 128 SX18_4N Imm ; Sign Extend Imm * 4
m_genesis.kv 129 mov nPC, PC ; nPC := PC
m_genesis.kv 130 add nPC, 0x4 ; nPC := nPC + 4
m_genesis.kv 131 add nPC, Imm ; nPC := nPC + Offset
m_genesis.kv 132 Flg_On InDelaySlot ; Set 'Delay Slot' Flag.
m_genesis.kv 133 jmp _end_cycle
m_genesis.kv 134 ; Not Taken:
m_genesis.kv 135 _i_bltzl_not_taken:
m_genesis.kv 136 add PC, 0x4 ; PC := PC + 4
m_genesis.kv 137 jmp _end_cycle
m_genesis.kv 138 ;-----------------------------------------------------------------------------
m_genesis.kv 139
m_genesis.kv 140 ;-----------------------------------------------------------------------------
m_genesis.kv 141 ; BGEZL - Branch on Greater Than or Equal to Zero Likely.
m_genesis.kv 142 ; Test a register, then do a PC-relative conditional branch;
m_genesis.kv 143 ; execute the delay slot only if the branch is taken.
m_genesis.kv 144 ; An 18-bit signed offset (the 16-bit offset field shifted left 2 bits) is
m_genesis.kv 145 ; added to the address of the instruction following the branch (not the branch
m_genesis.kv 146 ; itself), in the branch delay slot, to form a PC-relative effective target
m_genesis.kv 147 ; address. If the contents of rS are greater than or equal to zero
m_genesis.kv 148 ; (sign bit is 0), branch to the effective target address after the
m_genesis.kv 149 ; instruction in the delay slot is executed. If the branch is not taken, the
m_genesis.kv 150 ; instruction in the delay slot is not executed.
m_genesis.kv 151 ; Operation: if rS >= 0 then PC = PC + sign_extend(offset)
m_genesis.kv 152 ; else: nullify_current_instruction
m_genesis.kv 153 ; Syntax: bgezl $s, offset
m_genesis.kv 154 ; Encoding: 0000 01ss sss0 0011 iiii iiii iiii iiii
m_genesis.kv 155 ;-----------------------------------------------------------------------------
m_genesis.kv 156 align GRAIN, db 0x90
m_genesis.kv 157 _b_bgezl:
m_genesis.kv 158 IType_S_Only ; Load only rS Field just now
m_genesis.kv 159 cmp R(rS), 0 ; CMP(Regs[rS], 0)
m_genesis.kv 160 jnge _i_bgezl_not_taken ; If !(Regs[rS] >= 0) then NotTaken
m_genesis.kv 161 ; Taken:
m_genesis.kv 162 IType_I_Only ; Load only Imm Field just now
m_genesis.kv 163 SX18_4N Imm ; Sign Extend Imm * 4
m_genesis.kv 164 mov nPC, PC ; nPC := PC
m_genesis.kv 165 add nPC, 0x4 ; nPC := nPC + 4
m_genesis.kv 166 add nPC, Imm ; nPC := nPC + Offset
m_genesis.kv 167 Flg_On InDelaySlot ; Set 'Delay Slot' Flag.
m_genesis.kv 168 jmp _end_cycle
m_genesis.kv 169 ; Not Taken:
m_genesis.kv 170 _i_bgezl_not_taken:
m_genesis.kv 171 add PC, 0x4 ; PC := PC + 4
m_genesis.kv 172 jmp _end_cycle
m_genesis.kv 173 ;-----------------------------------------------------------------------------
m_genesis.kv 174
m_genesis.kv 175 ;-----------------------------------------------------------------------------
m_genesis.kv 176 ; BLTZAL -- Branch on less than zero and link.
m_genesis.kv 177 ; Branches if the register is less than zero and saves the return address
m_genesis.kv 178 ; in $31
m_genesis.kv 179 ; Operation: if $s < 0 $31 = PC + 8 (or nPC + 4); advance_pc(offset << 2));
m_genesis.kv 180 ; else advance_pc(4);
m_genesis.kv 181 ; Syntax: bltzal $s, offset
m_genesis.kv 182 ; Encoding: 0000 01ss sss1 0000 iiii iiii iiii iiii
m_genesis.kv 183 ;-----------------------------------------------------------------------------
m_genesis.kv 184 align GRAIN, db 0x90
m_genesis.kv 185 _b_bltzal:
m_genesis.kv 186 IType_I_S_Only ; Load rS and Imm Fields
m_genesis.kv 187 mov nPC, PC ; nPC := PC
m_genesis.kv 188 add nPC, 0x4 ; nPC := nPC + 4
m_genesis.kv 189 mov TMP, nPC ; TMP := nPC
m_genesis.kv 190 add TMP, 0x4 ; TMP := TMP + 4
m_genesis.kv 191 mov R(31), TMP ; Regs[31] := TMP
m_genesis.kv 192 SX18_4N Imm ; Sign Extend Imm * 4
m_genesis.kv 193 mov TMP, 0x4 ; TMP := 4
m_genesis.kv 194 cmp R(rS), 0 ; If Regs[rS] < 0:
m_genesis.kv 195 cmovl TMP, Imm ; ... then TMP := Imm
m_genesis.kv 196 add nPC, TMP ; nPC := nPC + TMP
m_genesis.kv 197 Flg_On InDelaySlot ; Set 'Delay Slot' Flag.
m_genesis.kv 198 jmp _end_cycle
m_genesis.kv 199 ;-----------------------------------------------------------------------------
m_genesis.kv 200
m_genesis.kv 201 ;-----------------------------------------------------------------------------
m_genesis.kv 202 ; BGEZAL -- Branch on greater than or equal to zero and link.
m_genesis.kv 203 ; Branches if the register is greater than or equal to zero and saves the
m_genesis.kv 204 ; return address in $31
m_genesis.kv 205 ; Operation: if $s >= 0 $31 = PC + 8 (or nPC + 4); advance_pc(offset << 2));
m_genesis.kv 206 ; else advance_pc(4);
m_genesis.kv 207 ; Syntax: bgezal $s, offset
m_genesis.kv 208 ; Encoding: 0000 01ss sss1 0001 iiii iiii iiii iiii
m_genesis.kv 209 ;-----------------------------------------------------------------------------
m_genesis.kv 210 align GRAIN, db 0x90
m_genesis.kv 211 _b_bgezal:
m_genesis.kv 212 IType_I_S_Only ; Load rS and Imm Fields
m_genesis.kv 213 mov nPC, PC ; nPC := PC
m_genesis.kv 214 add nPC, 0x4 ; nPC := nPC + 4
m_genesis.kv 215 mov TMP, nPC ; TMP := nPC
m_genesis.kv 216 add TMP, 0x4 ; TMP := TMP + 4
m_genesis.kv 217 mov R(31), TMP ; Regs[31] := TMP
m_genesis.kv 218 SX18_4N Imm ; Sign Extend Imm * 4
m_genesis.kv 219 mov TMP, 0x4 ; TMP := 4
m_genesis.kv 220 cmp R(rS), 0 ; If Regs[rS] < 0:
m_genesis.kv 221 cmovnl TMP, Imm ; ... then TMP := Imm
m_genesis.kv 222 add nPC, TMP ; nPC := nPC + TMP
m_genesis.kv 223 Flg_On InDelaySlot ; Set 'Delay Slot' Flag.
m_genesis.kv 224 jmp _end_cycle
m_genesis.kv 225 ;-----------------------------------------------------------------------------