-
+ 0049B58D97622DD2210F1547D96A7A69606C9EF7FD46349B1B16DB6E5A6F686D84296BCB2CCEEA2240A5BD82E46D1AC5A03C6C131F14906FC0E173C1A9A46B58
m/mipsinst/b_instrs.asm
(0 . 0)(1 . 225)
2126 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2127 ;; ;;
2128 ;; This file is part of 'M', a MIPS system emulator. ;;
2129 ;; ;;
2130 ;; (C) 2019 Stanislav Datskovskiy ( www.loper-os.org ) ;;
2131 ;; http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html ;;
2132 ;; ;;
2133 ;; You do not have, nor can you ever acquire the right to use, copy or ;;
2134 ;; distribute this software ; Should you use this software for any purpose, ;;
2135 ;; or copy and distribute it to anyone or in any manner, you are breaking ;;
2136 ;; the laws of whatever soi-disant jurisdiction, and you promise to ;;
2137 ;; continue doing so for the indefinite future. In any case, please ;;
2138 ;; always : read and understand any software ; verify any PGP signatures ;;
2139 ;; that you use - for any purpose. ;;
2140 ;; ;;
2141 ;; See also http://trilema.com/2015/a-new-software-licensing-paradigm . ;;
2142 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2143
2144 ;-----------------------------------------------------------------------------
2145 section .rodata
2146 align GRAIN, db 0x90
2147 _B_Table:
2148 A32 _b_bltz ; 0x00 : bltz (000001?????00000????????????????)
2149 A32 _b_bgez ; 0x01 : bgez (000001?????00001????????????????)
2150 A32 _b_bltzl ; 0x02 : bltzl (000001?????00010????????????????)
2151 A32 _b_bgezl ; 0x03 : bgezl (000001?????00011????????????????)
2152 A32 _bad ; 0x04 : UNDEFINED
2153 A32 _bad ; 0x05 : UNDEFINED
2154 A32 _bad ; 0x06 : UNDEFINED
2155 A32 _bad ; 0x07 : UNDEFINED
2156 A32 _bad ; 0x08 : UNDEFINED
2157 A32 _bad ; 0x09 : UNDEFINED
2158 A32 _bad ; 0x0a : UNDEFINED
2159 A32 _bad ; 0x0b : UNDEFINED
2160 A32 _bad ; 0x0c : UNDEFINED
2161 A32 _bad ; 0x0d : UNDEFINED
2162 A32 _bad ; 0x0e : UNDEFINED
2163 A32 _bad ; 0x0f : UNDEFINED
2164 A32 _b_bltzal ; 0x10 : bltzal (000001????x10000????????????????)
2165 A32 _b_bgezal ; 0x11 : bgezal (000001????x10001????????????????)
2166 A32 _bad ; 0x12 : UNDEFINED
2167 A32 _bad ; 0x13 : UNDEFINED
2168 A32 _bad ; 0x14 : UNDEFINED
2169 A32 _bad ; 0x15 : UNDEFINED
2170 A32 _bad ; 0x16 : UNDEFINED
2171 A32 _bad ; 0x17 : UNDEFINED
2172 A32 _bad ; 0x18 : UNDEFINED
2173 A32 _bad ; 0x19 : UNDEFINED
2174 A32 _bad ; 0x1a : UNDEFINED
2175 A32 _bad ; 0x1b : UNDEFINED
2176 A32 _bad ; 0x1c : UNDEFINED
2177 A32 _bad ; 0x1d : UNDEFINED
2178 A32 _bad ; 0x1e : UNDEFINED
2179 A32 _bad ; 0x1f : UNDEFINED
2180 ;-----------------------------------------------------------------------------
2181
2182 section .text
2183
2184 ;-----------------------------------------------------------------------------
2185 ; B-Type Instructions :
2186 ;-----------------------------------------------------------------------------
2187
2188 ;-----------------------------------------------------------------------------
2189 ; BLTZ -- Branch on less than zero.
2190 ; Branches if the register is less than zero
2191 ; Operation: if $s < 0 advance_pc(offset << 2)); else advance_pc(4);
2192 ; Syntax: bltz $s, offset
2193 ; Encoding: 0000 01ss sss0 0000 iiii iiii iiii iiii
2194 ;-----------------------------------------------------------------------------
2195 align GRAIN, db 0x90
2196 _b_bltz:
2197 IType_I_S_Only ; load rS and Imm Fields
2198 mov nPC, PC ; nPC := PC
2199 add nPC, 0x4 ; nPC := nPC + 4
2200 SX18_4N Imm ; Sign Extend Imm * 4
2201 mov TMP, 0x4 ; TMP := 4
2202 cmp R(rS), 0 ; If Regs[rS] < 0:
2203 cmovl TMP, Imm ; ... then TMP := Imm
2204 add nPC, TMP ; nPC := nPC + TMP
2205 Flg_On InDelaySlot ; Set 'Delay Slot' Flag.
2206 jmp _end_cycle
2207 ;-----------------------------------------------------------------------------
2208
2209 ;-----------------------------------------------------------------------------
2210 ; BGEZ -- Branch on greater than or equal to zero.
2211 ; Branches if the register is greater than or equal to zero
2212 ; Operation: if $s >= 0 advance_pc(offset << 2)); else advance_pc(4);
2213 ; Syntax: bgez $s, offset
2214 ; Encoding: 0000 01ss sss0 0001 iiii iiii iiii iiii
2215 ;-----------------------------------------------------------------------------
2216 align GRAIN, db 0x90
2217 _b_bgez:
2218 IType_I_S_Only ; load rS and Imm Fields
2219 mov nPC, PC ; nPC := PC
2220 add nPC, 0x4 ; nPC := nPC + 4
2221 SX18_4N Imm ; Sign Extend Imm * 4
2222 mov TMP, 0x4 ; TMP := 4
2223 cmp R(rS), 0 ; If Regs[rS] >= 0:
2224 cmovge TMP, Imm ; ... then TMP := Imm
2225 add nPC, TMP ; nPC := nPC + TMP
2226 Flg_On InDelaySlot ; Set 'Delay Slot' Flag.
2227 jmp _end_cycle
2228 ;-----------------------------------------------------------------------------
2229
2230 ;-----------------------------------------------------------------------------
2231 ; BLTZL - Branch on Less Than Zero Likely.
2232 ; Test a register, then do a PC-relative conditional branch;
2233 ; execute the delay slot only if the branch is taken.
2234 ; An 18-bit signed offset (the 16-bit offset field shifted left 2 bits) is
2235 ; added to the address of the instruction following the branch (not the branch
2236 ; itself), in the branch delay slot, to form a PC-relative effective target
2237 ; address. If the contents of rS are less than zero (sign bit is 1), branch to
2238 ; the effective target address after the instruction in the delay slot is
2239 ; executed. If the branch is not taken, the instruction in the delay slot is
2240 ; not executed.
2241 ; Operation: if rS < 0 then PC = PC + sign_extend(offset)
2242 ; else: nullify_current_instruction
2243 ; Syntax: bltzl $s, offset
2244 ; Encoding: 0000 01ss sss0 0010 iiii iiii iiii iiii
2245 ;-----------------------------------------------------------------------------
2246 align GRAIN, db 0x90
2247 _b_bltzl:
2248 IType_S_Only ; load only rS Field just now
2249 cmp R(rS), 0 ; CMP(Regs[rS], 0)
2250 jnl _i_bltzl_not_taken ; If !(Regs[rS] < 0) then NotTaken
2251 ; Taken:
2252 IType_I_Only ; load only Imm Field just now
2253 SX18_4N Imm ; Sign Extend Imm * 4
2254 mov nPC, PC ; nPC := PC
2255 add nPC, 0x4 ; nPC := nPC + 4
2256 add nPC, Imm ; nPC := nPC + Offset
2257 Flg_On InDelaySlot ; Set 'Delay Slot' Flag.
2258 jmp _end_cycle
2259 ; Not Taken:
2260 _i_bltzl_not_taken:
2261 add PC, 0x4 ; PC := PC + 4
2262 jmp _end_cycle
2263 ;-----------------------------------------------------------------------------
2264
2265 ;-----------------------------------------------------------------------------
2266 ; BGEZL - Branch on Greater Than or Equal to Zero Likely.
2267 ; Test a register, then do a PC-relative conditional branch;
2268 ; execute the delay slot only if the branch is taken.
2269 ; An 18-bit signed offset (the 16-bit offset field shifted left 2 bits) is
2270 ; added to the address of the instruction following the branch (not the branch
2271 ; itself), in the branch delay slot, to form a PC-relative effective target
2272 ; address. If the contents of rS are greater than or equal to zero
2273 ; (sign bit is 0), branch to the effective target address after the
2274 ; instruction in the delay slot is executed. If the branch is not taken, the
2275 ; instruction in the delay slot is not executed.
2276 ; Operation: if rS >= 0 then PC = PC + sign_extend(offset)
2277 ; else: nullify_current_instruction
2278 ; Syntax: bgezl $s, offset
2279 ; Encoding: 0000 01ss sss0 0011 iiii iiii iiii iiii
2280 ;-----------------------------------------------------------------------------
2281 align GRAIN, db 0x90
2282 _b_bgezl:
2283 IType_S_Only ; Load only rS Field just now
2284 cmp R(rS), 0 ; CMP(Regs[rS], 0)
2285 jnge _i_bgezl_not_taken ; If !(Regs[rS] >= 0) then NotTaken
2286 ; Taken:
2287 IType_I_Only ; Load only Imm Field just now
2288 SX18_4N Imm ; Sign Extend Imm * 4
2289 mov nPC, PC ; nPC := PC
2290 add nPC, 0x4 ; nPC := nPC + 4
2291 add nPC, Imm ; nPC := nPC + Offset
2292 Flg_On InDelaySlot ; Set 'Delay Slot' Flag.
2293 jmp _end_cycle
2294 ; Not Taken:
2295 _i_bgezl_not_taken:
2296 add PC, 0x4 ; PC := PC + 4
2297 jmp _end_cycle
2298 ;-----------------------------------------------------------------------------
2299
2300 ;-----------------------------------------------------------------------------
2301 ; BLTZAL -- Branch on less than zero and link.
2302 ; Branches if the register is less than zero and saves the return address
2303 ; in $31
2304 ; Operation: if $s < 0 $31 = PC + 8 (or nPC + 4); advance_pc(offset << 2));
2305 ; else advance_pc(4);
2306 ; Syntax: bltzal $s, offset
2307 ; Encoding: 0000 01ss sss1 0000 iiii iiii iiii iiii
2308 ;-----------------------------------------------------------------------------
2309 align GRAIN, db 0x90
2310 _b_bltzal:
2311 IType_I_S_Only ; Load rS and Imm Fields
2312 mov nPC, PC ; nPC := PC
2313 add nPC, 0x4 ; nPC := nPC + 4
2314 mov TMP, nPC ; TMP := nPC
2315 add TMP, 0x4 ; TMP := TMP + 4
2316 mov R(31), TMP ; Regs[31] := TMP
2317 SX18_4N Imm ; Sign Extend Imm * 4
2318 mov TMP, 0x4 ; TMP := 4
2319 cmp R(rS), 0 ; If Regs[rS] < 0:
2320 cmovl TMP, Imm ; ... then TMP := Imm
2321 add nPC, TMP ; nPC := nPC + TMP
2322 Flg_On InDelaySlot ; Set 'Delay Slot' Flag.
2323 jmp _end_cycle
2324 ;-----------------------------------------------------------------------------
2325
2326 ;-----------------------------------------------------------------------------
2327 ; BGEZAL -- Branch on greater than or equal to zero and link.
2328 ; Branches if the register is greater than or equal to zero and saves the
2329 ; return address in $31
2330 ; Operation: if $s >= 0 $31 = PC + 8 (or nPC + 4); advance_pc(offset << 2));
2331 ; else advance_pc(4);
2332 ; Syntax: bgezal $s, offset
2333 ; Encoding: 0000 01ss sss1 0001 iiii iiii iiii iiii
2334 ;-----------------------------------------------------------------------------
2335 align GRAIN, db 0x90
2336 _b_bgezal:
2337 IType_I_S_Only ; Load rS and Imm Fields
2338 mov nPC, PC ; nPC := PC
2339 add nPC, 0x4 ; nPC := nPC + 4
2340 mov TMP, nPC ; TMP := nPC
2341 add TMP, 0x4 ; TMP := TMP + 4
2342 mov R(31), TMP ; Regs[31] := TMP
2343 SX18_4N Imm ; Sign Extend Imm * 4
2344 mov TMP, 0x4 ; TMP := 4
2345 cmp R(rS), 0 ; If Regs[rS] < 0:
2346 cmovnl TMP, Imm ; ... then TMP := Imm
2347 add nPC, TMP ; nPC := nPC + TMP
2348 Flg_On InDelaySlot ; Set 'Delay Slot' Flag.
2349 jmp _end_cycle
2350 ;-----------------------------------------------------------------------------