-
+ 0049B58D97622DD2210F1547D96A7A69606C9EF7FD46349B1B16DB6E5A6F686D84296BCB2CCEEA2240A5BD82E46D1AC5A03C6C131F14906FC0E173C1A9A46B58m/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 ;-----------------------------------------------------------------------------