Ну я там выше писал ведь примеры - MIN, MAX, MSK, CMP и может быть SUMhaqreu wrote:Можешь привести сценарий использования OPB?
То какие расширенные команды точно нужны можно проверить скажем на подпрограмме умножения триад, на выходе которой получается 6-тритный результат:
Code: Select all
ORG NNNNNN
; Multiply R1 and R2, store result at R4,R3
; At this point R4,R3 have return address because we jumped here using JPI
; We save them to R12,R11 and also will use R6,R5 to shift 1st argument left
; In the same time we will shift 2nd argument (R7) right until it becomes zero
LMUL:
; R5 = R1
RR -5 ; NNN NNN
; R6 = 0
R1 0 ; NNN NNO
RR -6 ; NNN NNP
; Increment R1 that is zero, so C must be zero after that
RR 1 ; NNN NON
; R12 = R4
RR 4 ; NNN NOO
RR -12 ; NNN NOP
; R11 = R3
RR 3 ; NNN NPN
RR -11 ; NNN NPO
; R4,R3 = 0
R4 0 ; NNN NPP
R3 0 ; NNN ONN
; Transfer R2 to R7 through R1
RR 2 ; NNN ONO
RR -7 ; NNN ONP
L1: ;NNN OON - Beginning of the loop
; Shift R7 right through C
EX RRC ; NNN OON
RR -7 ; NNN OOO
; Skip if C==O
SK 0 ; NNN OOP
JP L2 ; NNN OPN
; Long jump to the end of the loop (L5)
R1 NNO ; NNN OPO
RR -13 ; NNN OPP
JP L5 ; NNN PNN
L2: ;NNN PNO - We here because C!=O
; Skip if C==N
SK -1 ; NNN PNO
JP L3 ; NNN PNP
; Long jump to negative case (L4)
R1 NNO ; NNN PON
RR -13 ; NNN POO
JP L4 ; NNN POP
L3: ;NNN PPN - We here becauae C==P
; R3 += R5
RR 5 ; NNN PPN
RR -2 ; NNN PPO
RR 3 ; NNN PPP
EX ADD ; NNO NNN
RR -3 ; NNO NNO
; R4 += R6 with C
RR 6 ; NNO NNP
RR -2 ; NNO NON
RR 4 ; NNO NOO
EX ADC ; NNO NOP
RR -4 ; NNO NPN
; Jump to the end of the loop (L5)
JP L5 ; NNO NPO
L4: ;NNO NPP - We here because C==N
; R3 -= R5
RR 5 ; NNO NPP
RR -2 ; NNO ONN
RR 3 ; NNO ONO
EX SUB ; NNO ONP
RR -3 ; NNO OON
; R4 -= R6 with C
RR 6 ; NNO OOO
RR -2 ; NNO OOP
RR 4 ; NNO OPN
EX SBC ; NNO OPO
RR -4 ; NNO OPP
L5: ;NNO PNN - End of the loop
; Shift R6,R5 left (here C must be zero)
RR 5 ; NNO PNN
EX RLC ; NNO PNO
RR -5 ; NNO PNP
RR 6 ; NNO PON
EX RLC ; NNO POO
RR -6 ; NNO POP
; Do nothing
OP NOP ; NNO PPN
; Check if R7 is zero
RR 7 ; NNO PPO
; Skip if R1!=0
SK -3 ; NNO PPP
JP L6 ; NNP NNN
; Increment R1 that is Oxx already, so C must be zero after that
RR 1 ; NNP NNO
; Long jump to the beginning of the loop (L1)
R1 NNN ; NNP NNP
RR -13 ; NNP NON
JP L1 ; NNP NOO
L6: ;NNP NOP - We are here because R7 is zero - RETURN
RR 12 ; NNP NOP
RR -13 ; NNP NPN
RR 11 ; NNP NPO
RR -2 ; NNP NPP
EX JPI ; NNP ONN
P.S. Для первоначального RLC/RRC пришлось обнулять флаг C таким образом:
R1 0 ; R1=0
RR 1 ; R1++ (C=O)
поэтому отдельная команда обнуления переноса CLC не помешала бы ( и её кстати можно изобразить из супер-пупер программируемой пермутации, что я изобрёл на предыдущей странице как собственно и RLC/RRC : )
P.P.S. Анализатор наличия переноса/заёма на самом деле относительно простой - для сложения:
SK 0 ; skip if C==O
RR 1 ; R1++
и для вычитания:
SK 0 ; skip if C==O
RR -1 ; R1--
так что возможно ADC и SBC действительно ненужны
P.P.P.S. По поводу ненужности SUB - по идее таки да, чтобы изобразить R2-R1 надо лишь OP PON сделать перед сложением - вот вариант где кроме JPI есть только RLC,RRC и ADD, и он только на 6 инструкций длиннее:
Code: Select all
ORG NNNNNN
; Multiply R1 and R2, store result at R4,R3
; At this point R4,R3 have return address because we jumped here using JPI
; We save them to R12,R11 and also will use R6,R5 to shift 1st argument left
; In the same time we will shift 2nd argument (R7) right until it becomes zero
LMUL:
; R5 = R1
RR -5 ; NNN NNN
; R6 = 0
R1 0 ; NNN NNO
RR -6 ; NNN NNP
; Increment R1 that is zero, so C must be zero after that
RR 1 ; NNN NON
; R12 = R4
RR 4 ; NNN NOO
RR -12 ; NNN NOP
; R11 = R3
RR 3 ; NNN NPN
RR -11 ; NNN NPO
; R4,R3 = 0
R4 0 ; NNN NPP
R3 0 ; NNN ONN
; Transfer R2 to R7 through R1
RR 2 ; NNN ONO
RR -7 ; NNN ONP
L1: ;NNN OON - Beginning of the loop
; Shift R7 right through C
EX RRC ; NNN OON
RR -7 ; NNN OOO
; Skip if C==O
SK 0 ; NNN OOP
JP L2 ; NNN OPN
; Long jump to the end of the loop (L5)
R1 NNO ; NNN OPO
RR -13 ; NNN OPP
JP L5 ; NNN PNN
L2: ;NNN PNO - We here because C!=O
; Skip if C==N
SK -1 ; NNN PNO
JP L3 ; NNN PNP
; Long jump to negative case (L4)
R1 NNO ; NNN PON
RR -13 ; NNN POO
JP L4 ; NNN POP
L3: ;NNN PPN - We here becauae C==P
; R3 += R5
RR 5 ; NNN PPN
RR -2 ; NNN PPO
RR 3 ; NNN PPP
EX ADD ; NNO NNN
RR -3 ; NNO NNO
; R4 += R6 with C
RR 6 ; NNO NNP
RR -2 ; NNO NON
RR 4 ; NNO NOO
SK 0 ; NNO NOP
RR 1 ; NNO NPN
EX ADD ; NNO NPO
RR -4 ; NNO NPP
; Jump to the end of the loop (L5)
JP L5 ; NNO ONN
L4: ;NNO ONO - We here because C==N
; R3 -= R5
RR 3 ; NNO ONO
RR -2 ; NNO ONP
RR 5 ; NNO OON
OP PON ; NNO OOO
EX ADD ; NNO OOP
RR -3 ; NNO OPN
; R4 -= R6 with C
RR 4 ; NNO OPO
RR -2 ; NNO OPP
RR 6 ; NNO PNN
OP PON ; NNO PNO
SK 0 ; NNO PNP
RR -1 ; NNO PON
EX ADD ; NNO POO
RR -4 ; NNO POP
L5: ;NNO PPN - End of the loop
; Shift R6,R5 left (here C must be zero)
RR 5 ; NNO PPN
EX RLC ; NNO PPO
RR -5 ; NNO PPP
RR 6 ; NNP NNN
EX RLC ; NNP NNO
RR -6 ; NNP NNP
; Do nothing
OP NOP ; NNP NON
; Check if R7 is zero
RR 7 ; NNP NOO
; Skip if R1!=0
SK -3 ; NNP NOP
JP L6 ; NNP NPN
; Increment R1 that is Oxx already, so C must be zero after that
RR 1 ; NNP NPO
; Long jump to the beginning of the loop (L1)
R1 NNN ; NNP NPP
RR -13 ; NNP ONN
JP L1 ; NNP ONO
L6: ;NNP ONP - We are here because R7 is zero - RETURN
RR 12 ; NNP ONP
RR -13 ; NNP OON
RR 11 ; NNP OOO
RR -2 ; NNP OOP
EX JPI ; NNP OPN