Dalsi varka pravidelneho a podle pravidel fora legalniho spamu... .)
Hral jsem si dnes s temi bitovymi posuny. Mel jsem pro double hodnotu funkci, ale jak jsem delal pro pointery posun o konstantni pocet bitu, tak jsem to pridal pro obycene double.
Nedelal jsem vsech 32 posunu a pro obe strany, ale jen o 1,4,8,16,24 bitu. Prinejhorsim se zbytek da z toho neprilis efektivne nakombinovat.
Chtel jsem to porovnat s ZCC kompilerem, ale po "mensim" boji, kdy se mi to podarilo zprovoznit na
https://godbolt.org/ kompiler exploreru. (Funguje to kdyz pridate parametr -zx) Prislo zklamani, ze umi rotace jen u 16 bitovych integeru...
Urcite se uz strasne tesite na kod, takze tady je. Nic jsem par dnu netestoval, takze pokud se na to nekdo fakt koukne a najde chybu nebo lepsi reseni tak se nebojte ozvat.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_1_DLSHIFT'
add HL, HL ; 1:11 1 dlshift ( d1 1 -- d ) d = d1 << 1
rl E ; 2:8 1 dlshift
rl D ; 2:8 1 dlshift
;[ 5:27]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_1_DRSHIFT'
srl D ; 2:8 1 drshift ( d1 1 -- d ) d = d1 >> 1
rr E ; 2:8 1 drshift
rr H ; 2:8 1 drshift
rr L ; 2:8 1 drshift
;[ 8:32]
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_1_PDLSHIFT'
ld C, L ; 1:4 1 pdlshift ( pd 1 -- pd ) [pd] <<= 1 with align 4
ld A,(HL) ; 1:7 1 pdlshift
add A, A ; 1:4 1 pdlshift
ld (HL),A ; 1:7 1 pdlshift
inc L ; 1:4 1 pdlshift
rl (HL) ; 2:15 1 pdlshift
inc L ; 1:4 1 pdlshift
rl (HL) ; 2:15 1 pdlshift
inc L ; 1:4 1 pdlshift
rl (HL) ; 2:15 1 pdlshift
ld L, C ; 1:4 1 pdlshift
;[14:83]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_1_PDRSHIFT'
inc L ; 1:4 1 pdrshift ( pd 1 -- pd ) [pd] >>= 1 with align 4
inc L ; 1:4 1 pdrshift
inc L ; 1:4 1 pdrshift
xor A ; 1:4 1 pdrshift
rr (HL) ; 2:15 1 pdrshift
dec L ; 1:4 1 pdrshift
rr (HL) ; 2:15 1 pdrshift
dec L ; 1:4 1 pdrshift
rr (HL) ; 2:15 1 pdrshift
dec L ; 1:4 1 pdrshift
rr (HL) ; 2:15 1 pdrshift
;[15:88]
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_4_DLSHIFT'
ld A, E ; 1:4 4 dlshift ( d1 4 -- d ) d = d1 << 4
add HL, HL ; 1:11 4 dlshift
adc A, A ; 1:4 4 dlshift
rl D ; 2:8 4 dlshift
add HL, HL ; 1:11 4 dlshift
adc A, A ; 1:4 4 dlshift
rl D ; 2:8 4 dlshift
add HL, HL ; 1:11 4 dlshift
adc A, A ; 1:4 4 dlshift
rl D ; 2:8 4 dlshift
add HL, HL ; 1:11 4 dlshift
adc A, A ; 1:4 4 dlshift
rl D ; 2:8 4 dlshift
ld E, A ; 1:4 4 dlshift
;[18:100]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_4_DRSHIFT'
;[25:128] 4 drshift ( d1 4 -- d ) d = d1 >> 4
ld A, E ; 1:4 4 drshift
add HL, HL ; 1:11 4 drshift 654321->5432.10
adc A, A ; 1:4 4 drshift
add HL, HL ; 1:11 4 drshift 654321->5432.10
adc A, A ; 1:4 4 drshift
add HL, HL ; 1:11 4 drshift 654321->5432.10
adc A, A ; 1:4 4 drshift
add HL, HL ; 1:11 4 drshift 654321->5432.10
adc A, A ; 1:4 4 drshift
ld L, H ; 1:4 4 drshift
ld H, A ; 1:4 4 drshift
ld A, E ; 1:4 4 drshift
srl D ; 2:8 4 drshift 8765->0876
rra ; 1:4 4 drshift
srl D ; 2:8 4 drshift 8765->0876
rra ; 1:4 4 drshift
srl D ; 2:8 4 drshift 8765->0876
rra ; 1:4 4 drshift
srl D ; 2:8 4 drshift 8765->0876
rra ; 1:4 4 drshift
ld E, A ; 1:4 4 drshift
;[25:128]
Tady ta rotace vpravo je celkem orisek jak to resit. Radsi ukazi jeste jak vypada kod, mam tam radsi vsechno co jsem psal, vcetne prvniho nejmene efektivniho reseni.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'dumpdef({__ASM_TOKEN_4_DRSHIFT})'
__ASM_TOKEN_4_DRSHIFT: dnl
__{}define({__INFO},__COMPILE_INFO){}dnl
__{}ifelse(1,1,{
;[25:128] __INFO ( d1 4 -- d ) d = d1 >> 4
ld A, E ; 1:4 __INFO
add HL, HL ; 1:11 __INFO 654321->5432.10
adc A, A ; 1:4 __INFO
add HL, HL ; 1:11 __INFO 654321->5432.10
adc A, A ; 1:4 __INFO
add HL, HL ; 1:11 __INFO 654321->5432.10
adc A, A ; 1:4 __INFO
add HL, HL ; 1:11 __INFO 654321->5432.10
adc A, A ; 1:4 __INFO
ld L, H ; 1:4 __INFO
ld H, A ; 1:4 __INFO
ld A, E ; 1:4 __INFO
srl D ; 2:8 __INFO 8765->0876
rra ; 1:4 __INFO
srl D ; 2:8 __INFO 8765->0876
rra ; 1:4 __INFO
srl D ; 2:8 __INFO 8765->0876
rra ; 1:4 __INFO
srl D ; 2:8 __INFO 8765->0876
rra ; 1:4 __INFO
ld E, A ; 1:4 __INFO},
1,1,{
;[30:120] __INFO ( d1 4 -- d ) d = d1 >> 4
ld A, E ; 1:4 __INFO
srl D ; 2:8 __INFO 87654321->08765432
rra ; 1:4 __INFO
rr H ; 2:8 __INFO
rr L ; 2:8 __INFO
srl D ; 2:8 __INFO 87654321->08765432
rra ; 1:4 __INFO
rr H ; 2:8 __INFO
rr L ; 2:8 __INFO
srl D ; 2:8 __INFO 87654321->08765432
rra ; 1:4 __INFO
rr H ; 2:8 __INFO
rr L ; 2:8 __INFO
srl D ; 2:8 __INFO 87654321->08765432
rra ; 1:4 __INFO
rr H ; 2:8 __INFO
rr L ; 2:8 __INFO
ld E, A ; 1:4 __INFO},
{
;[24:152] __INFO ( d1 4 -- d ) d = d1 >> 4
ld A, E ; 1:4 __INFO
add HL, HL ; 1:11 __INFO 654321->5432.10
adc A, A ; 1:4 __INFO
add HL, HL ; 1:11 __INFO 654321->5432.10
adc A, A ; 1:4 __INFO
add HL, HL ; 1:11 __INFO 654321->5432.10
adc A, A ; 1:4 __INFO
add HL, HL ; 1:11 __INFO 654321->5432.10
adc A, A ; 1:4 __INFO
ld L, H ; 1:4 __INFO
ld H, A ; 1:4 __INFO
xor A ; 1:4 __INFO
ex DE, HL ; 1:4 __INFO
add HL, HL ; 1:11 __INFO 008765->0876.50
adc A, A ; 1:4 __INFO
add HL, HL ; 1:11 __INFO 008765->0876.50
adc A, A ; 1:4 __INFO
add HL, HL ; 1:11 __INFO 008765->0876.50
adc A, A ; 1:4 __INFO
add HL, HL ; 1:11 __INFO 008765->0876.50
adc A, A ; 1:4 __INFO
ex DE, HL ; 1:4 __INFO
ld E, D ; 1:4 __INFO
ld D, A ; 1:4 __INFO}){}dnl
;[ 0:0]
Ted prijde zlaty hreb vecera (1:09 Greenwitch time, tak asi noci)
Snazil jsem se to smysluplne okomentovat. Mam na mysli RLD, RRD instrukce.
To ze mam v informaci jak vypada zasobnik vsude i tu ciselnou konstantu je mozna trosku matouci, protoze tam jeste neni a po konci uz nebude. Mluvim o tom ( pd 4 -- pd ), kde "pd" ma (podle me) znamenat "pointer to double". Mozna to tam fakt nepatri... hmm...
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_4_PDLSHIFT'
xor A ; 1:4 4 pdlshift ( pd 4 -- pd ) [pd] <<= 4 with align 4
rld ; 2:18 4 pdlshift A(HL)=0xA021-->0xA210
ld C, L ; 1:4 4 pdlshift
inc L ; 1:4 4 pdlshift
rld ; 2:18 4 pdlshift A(HL)=0xA243-->0xA432
inc L ; 1:4 4 pdlshift
rld ; 2:18 4 pdlshift A(HL)=0xA465-->0xA654
inc L ; 1:4 4 pdlshift
rld ; 2:18 4 pdlshift A(HL)=0xA687-->0xA876
ld L, C ; 1:4 4 pdlshift
;[14:96]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_4_PDRSHIFT'
inc L ; 1:4 4 pdrshift ( pd 4 -- pd ) [pd] >>= 4 with align 4
inc L ; 1:4 4 pdrshift
inc L ; 1:4 4 pdrshift
xor A ; 1:4 4 pdrshift
rrd ; 2:18 4 pdrshift A(HL)=0xA087-->0xA708
dec L ; 1:4 4 pdrshift
rrd ; 2:18 4 pdrshift A(HL)=0xA765-->0xA576
dec L ; 1:4 4 pdrshift
rrd ; 2:18 4 pdrshift A(HL)=0xA543-->0xA354
dec L ; 1:4 4 pdrshift
rrd ; 2:18 4 pdrshift A(HL)=0xA321-->0xA132
;[15:100]
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_8_DLSHIFT'
ld D, E ; 1:4 8 dlshift ( d1 8 -- d ) d = d1 << 8
ld E, H ; 1:4 8 dlshift
ld H, L ; 1:4 8 dlshift
ld L, 0x00 ; 2:7 8 dlshift
;[ 5:19]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_8_DRSHIFT'
ld L, H ; 1:4 8 drshift ( d1 8 -- d ) d = d1 >> 8
ld H, E ; 1:4 8 drshift
ld E, D ; 1:4 8 drshift
ld D, 0x00 ; 2:7 8 drshift
;[ 5:19]
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_8_PDLSHIFT'
ld C, L ; 1:4 8 pdlshift ( pd 8 -- pd ) [pd] <<= 8 with align 4
ld A,(HL) ; 1:7 8 pdlshift
ld (HL),0x00 ; 2:10 8 pdlshift
inc L ; 1:4 8 pdlshift
ld B,(HL) ; 1:7 8 pdlshift
ld (HL),A ; 1:7 8 pdlshift
inc L ; 1:4 8 pdlshift
ld A,(HL) ; 1:7 8 pdlshift
ld (HL),B ; 1:7 8 pdlshift
inc L ; 1:4 8 pdlshift
ld (HL),A ; 1:7 8 pdlshift
ld L, C ; 1:4 8 pdlshift
;[13:72]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_8_PDRSHIFT'
inc L ; 1:4 8 pdrshift ( pd 8 -- pd ) [pd] >>= 8 with align 4
inc L ; 1:4 8 pdrshift
inc L ; 1:4 8 pdrshift
ld A,(HL) ; 1:7 8 pdrshift
ld (HL),0x00 ; 2:10 8 pdrshift
dec L ; 1:4 8 pdrshift
ld B,(HL) ; 1:7 8 pdrshift
ld (HL),A ; 1:7 8 pdrshift
dec L ; 1:4 8 pdrshift
ld A,(HL) ; 1:7 8 pdrshift
ld (HL),B ; 1:7 8 pdrshift
dec L ; 1:4 8 pdrshift
ld (HL),A ; 1:7 8 pdrshift
;[14:76]
Nebudete tomu mozna verit, ale u posunu o 16 bitu jsem mel puvodne kod obdobny jako u posunu o 8 bitu a vubec me nedoslo, ze to jde udelat mnohem lepe.
Kód:
- ld D, H ; 1:4 __INFO ( d1 16 -- d ) d = d1 << 16
- ld E, L ; 1:4 __INFO
- ld H, 0x00 ; 2:7 __INFO
- ld L, H ; 1:4 __INFO}){}dnl
+ ex DE, HL ; 1:4 __INFO ( d1 16 -- d ) d = d1 << 16
+ ld HL, 0x0000 ; 3:10 __INFO}){}dnl
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_16_DLSHIFT'
ex DE, HL ; 1:4 16 dlshift ( d1 16 -- d ) d = d1 << 16
ld HL, 0x0000 ; 3:10 16 dlshift
;[ 4:14]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_16_DRSHIFT'
ld DE, HL ; 1:4 16 drshift ( d1 16 -- d ) d = d1 >> 16
ld DE, 0x0000 ; 3:10 16 drshift
;[ 4:14]
U "16 pdlshift" me chybi jeden volny osmibitovy registr, abych se zbavil dvou "ld (HL),0x00" instrukci a nahradil je "xor A" a dvema "ld (HL),A" instrukcema. Proto je ten posun vlevo stejne velky jak vpravo a jen o 2 takty rychlejsi.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_16_PDLSHIFT'
ld C, L ; 1:4 16 pdlshift ( pd 16 -- pd ) [pd] <<= 16 with align 4
ld A,(HL) ; 1:7 16 pdlshift
ld (HL),0x00 ; 2:10 16 pdlshift
inc L ; 1:4 16 pdlshift
ld B,(HL) ; 1:7 16 pdlshift
ld (HL),0x00 ; 2:10 16 pdlshift
inc L ; 1:4 16 pdlshift
ld (HL),A ; 1:7 16 pdlshift
inc L ; 1:4 16 pdlshift
ld (HL),B ; 1:7 16 pdlshift
ld L, C ; 1:4 16 pdlshift
;[13:68]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_16_PDRSHIFT'
inc L ; 1:4 16 pdrshift ( pd 16 -- pd ) [pd] >>= 16 with align 4
inc L ; 1:4 16 pdrshift
inc L ; 1:4 16 pdrshift
xor A ; 1:4 16 pdrshift
ld B,(HL) ; 1:7 16 pdrshift
ld (HL),A ; 1:7 16 pdrshift
dec L ; 1:4 16 pdrshift
ld C,(HL) ; 1:7 16 pdrshift
ld (HL),A ; 1:7 16 pdrshift
dec L ; 1:4 16 pdrshift
ld (HL),B ; 1:7 16 pdrshift
dec L ; 1:4 16 pdrshift
ld (HL),C ; 1:7 16 pdrshift
;[13:70]
A posledni hodnota o 24 byla puvodne o takt pomalejsi, ale jak jsem spravoval tu o 16 bitu tak uz to bylo snadne, i kdyz prekvapive nahradit za "ld reg16,0"
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_24_DLSHIFT'
ld D, L ; 1:4 24 dlshift ( d1 24 -- d ) d = d1 << 24
ld HL, 0x0000 ; 3:10 24 dlshift
ld E, L ; 1:4 24 dlshift
;[ 5:18]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_24_DRSHIFT'
ld L, D ; 1:4 24 drshift ( d1 24 -- d ) d = d1 >> 24
ld DE, 0x0000 ; 3:10 24 drshift
ld H, D ; 1:4 24 drshift
;[ 5:18]
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_24_PDLSHIFT'
ld C, L ; 1:4 24 pdlshift ( pd 24 -- pd ) [pd] <<= 24 with align 4
xor A ; 1:4 24 pdlshift
ld B,(HL) ; 1:7 24 pdlshift
ld (HL),A ; 1:7 24 pdlshift
inc L ; 1:4 24 pdlshift
ld (HL),A ; 1:7 24 pdlshift
inc L ; 1:4 24 pdlshift
ld (HL),A ; 1:7 24 pdlshift
inc L ; 1:4 24 pdlshift
ld (HL),B ; 1:7 24 pdlshift
ld L, C ; 1:4 24 pdlshift
;[11:59]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_24_PDRSHIFT'
ld C, L ; 1:4 24 pdrshift ( pd 24 -- pd ) [pd] >>= 24 with align 4
xor A ; 1:4 24 pdrshift
inc L ; 1:4 24 pdrshift
ld (HL),A ; 1:7 24 pdrshift
inc L ; 1:4 24 pdrshift
ld (HL),A ; 1:7 24 pdrshift
inc L ; 1:4 24 pdrshift
ld B,(HL) ; 1:7 24 pdrshift
ld (HL),A ; 1:7 24 pdrshift
ld L, C ; 1:4 24 pdrshift
ld (HL),B ; 1:7 24 pdrshift
;[11:59]
To je asi pro dnesek vse. Mozna nekdy dodelam posun o 12, protoze tam me vypadne u varinaty kdy to neni pointer jeden registr, takze to jde krasne resit jen pomoci "add HL,HL" a "rla/adc A,A".