|
nedoPC.orgCommunity for electronics hobbyists, established in 2002 |
|
[SDK] Новая математика для кросс-компилятора в 8080/z80
Author |
Message |
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 23285 Location: Silicon Valley
|
Арифметика у меня всегда через стек и я не могу на этапе компиляции определить что сидит в стеке - переменная или константа - поэтому остаётся только на лету смотреть и проверять в рантайме (на самом деле теоретически могу и на этапе компиляции, если начну искать паттерны в байткоде выражений)... P.S. Вот как ведут себя сдвиги 16-битного аргумента в Си (проверено в 64-битном GCC, 32-битном OpenWatcom-C/C++ и 16-битном Borland C++): Программа: Сделаю из этого тест 0003 P.P.S. Кстати я могу задействовать функционал по подсчёту тактов в эмуляторе Pseudo-86RK и сравнить время выполнения оригинальных сдвигов из Small-C и этих моих новых
|
21 Jul 2024 11:59 |
|
|
Mondx
Doomed
Joined: 10 Aug 2022 07:27 Posts: 378
|
Шаос, я не могу тебя учить. Но. Ты знаешь что такое стиль? Это то как ты одеваешься. Понятно, что провожают по уму, а не по одёжке, однако и по этому тоже. Ну есть же куча статей по стилю С/С++, почитал бы, не? А то, прям, воротит, ей богу.)
Last edited by Mondx on 21 Jul 2024 15:27, edited 1 time in total.
|
21 Jul 2024 15:24 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 23285 Location: Silicon Valley
|
Ну вот только в хобби не надо меня на тему кодингстайла лечить - мне на работе нытья на эту тему в кодревью хватает Для себя я пишу как хочу, как мне удобно, как привык ещё в ранние 90е, а не как наса предложила или гугол захотел Если непонятно, то открываем азы - там Кернигана и Ричи например - и подтягиваемся до нужного уровня
|
21 Jul 2024 15:57 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 23285 Location: Silicon Valley
|
Первые результаты прогона с подсчётом тактов - пока только сдвиги влево числа #1234 на количество бит от 0 до 32: Как можно видеть в самом начале моя подпрограмма чуть хуже (из-за проверок), но потом догоняет и обгоняет подпрограмму из Small-C ( а особый случай 8 вообще сильно лучше : ) Что касается правильности, то ответы совпадают от 0 до 31, а вот в случае 32 я по сишному делаю как сдвиг опять на 0 бит, возвращая #1234, а Small-C тупо двигает 32 раза влево, тратя на это 1000 с лишним тактов и выдавая ноль в качестве ответа! Завтра допишу тестовую прогу, чтобы проверяла сдвиг вправо положительного и отрицательного числа точно также от 0 до 32 и выложу саму прогу и xls-файл с табличкой и графиком... P.S. Вот тут есть объяснение почему сдвиг на 32 может означать сдвиг на 0: https://stackoverflow.com/questions/2648764/whats-bad-about-shifting-a-32-bit-variable-32-bits
|
22 Jul 2024 01:41 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 23285 Location: Silicon Valley
|
Окончательный график (для Small-C сдвиг вправо одинаковый для положительных и отрицательных чисел, а у меня разница 4 такта, но на графике тоже не сильно видно): Короче где-то после 5 у меня всё быстрее и быстрее Ну и сдвиг на 8 совсем быстро Текст программы в мнемониках RASM будет в следующем сообщении (я придумал как немного ускорить сдвиг вправо)Выхлоп Pseudo-86RK со счётчиками: TEST1.OUT Экселевский файл (приготовлен в LibreOffice) обновлю и выложу чуть позже...
|
22 Jul 2024 20:31 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 23285 Location: Silicon Valley
|
Придумал как ускорить сдвиг в право на 1 такт для отрицательных и на 5 тактов для положительных чисел - теперь у меня цифры стали одинаковые для обоих вариантов, быстрее старого алгоритма из Small-C после 5 и сильно меньше при сдвиге на 8 | | | | Code: \ SHIFT DE RIGHT (ARITHMETICALLY) BY L&31 AND RETURN IN HL SHIFTR: XCHG MOV_A,E ANI 31 RZ \ RETURN IF SHIFT BY 0 MOV_D,A CPI 8 JZ SHIFTR3 ORA_H JM SHIFTR1 SHIFTR0: XRA_A MOV_A,H RAR MOV_H,A MOV_A,L RAR MOV_L,A DCR_D JNZ SHIFTR0 RET SHIFTR1: STC MOV_A,H RAR MOV_H,A MOV_A,L RAR MOV_L,A DCR_D JNZ SHIFTR1 RET SHIFTR3: \ SPECIAL CASE - SHIFT BY 8 MOV_L,H ORA_H JM SHIFTR4 MVI_H, 0 RET SHIFTR4: MVI_H, #FF RET
| | | | |
Я просто пользуюсь тем фактом, что на момент проверки на знак в аккумуляторе сидит число от 0 до 31 у которого старший бит заведомо ноль т.е. я делаю ИЛИ с регистром H и получаю в старшем бите аккумулятора знак числа - переход при этом делается через JM (переход если минус) и из-за того что переход не по C перестал работать укорачивающий трюк при первом проходе для отрицательных чисел - поэтому теперь номера для положительных и отрицательных абсолютно одинаковые (как я уже выше написал): По числам по идее надо вычесть длительность команды-маркера MOV_A,A (-5 тактов) и добавить длительность команды POP_D, которая стоит перед вызовом этой подпрограммы в реальном сгенерированном коде, чтобы вытащить один из аргументов из стека (+10 тактов) - получается сдвиг на 0 бит занимает 49-5+10=54 такта (и влево, и вправо), сдвиг на 8 бит влево - 87 тактов, на 8 бит вправо - 106 тактов, а длительность всех остальных сдвигов от 1 до 31 вычисляются по формулам: - сдвиг влево: 75+N*25 тактов
- сдвиг вправо: 94+N*47 тактов
Текст тестовой программки: TEST1.A | | | | Code: @WORD = #1234
XRA_A LOOP: MOV_L,A MVI_H, 0 LXI_D, @WORD PUSH_PSW MOV_A,A CALL SHIFTL MOV_A,A SHLD RES1
POP_PSW MOV_L,A MVI_H, 0 LXI_D, @WORD PUSH_PSW MOV_A,A CALL CCASL_ MOV_A,A SHLD RES2
MOV_L,A MVI_H, 0 LXI_D, @WORD PUSH_PSW MOV_B,B CALL SHIFTR MOV_B,B SHLD RES3
POP_PSW MOV_L,A MVI_H, 0 LXI_D, @WORD PUSH_PSW MOV_B,B CALL CCASR_ MOV_B,B SHLD RES4
LXI_D, @WORD MOV_A,D CMA MOV_D,A MOV_A,E CMA MOV_E,A POP_PSW PUSH_D
MOV_L,A MVI_H, 0 PUSH_PSW MOV_C,C CALL SHIFTR MOV_C,C SHLD RES5
POP_PSW MOV_L,A MVI_H, 0 POP_D PUSH_PSW MOV_C,C CALL CCASR_ MOV_C,C SHLD RES6
LXI_H, STR1 CALL #F818 POP_PSW PUSH_PSW CALL #F815 LHLD RES1 CALL PRINTHL LHLD RES2 CALL PRINTHL LHLD RES3 CALL PRINTHL LHLD RES4 CALL PRINTHL LHLD RES5 CALL PRINTHL LHLD RES6 CALL PRINTHL LXI_H, STRN CALL #F818
POP_PSW INR_A CPI 33 JNZ LOOP
HLT
PRINTHL: PUSH_H MVI_C, 32 CALL #F809 MVI_C, '#' CALL #F809 POP_H PUSH_H MOV_A,H CALL #F815 POP_H MOV_A,L CALL #F815 RET
\ SHIFT DE LEFT BY L&31 AND RETURN IN HL SHIFTL: XCHG MOV_A,E ANI 31 RZ \ RETURN IF SHIFT BY 0 CPI 8 JNZ SHIFTL1 \ SPECIAL CASE - SHIFT BY 8 MOV_H,L MVI_L, 0 RET SHIFTL1: DAD_H DCR_A JNZ SHIFTL1 RET
\ SHIFT DE RIGHT (ARITHMETICALLY) BY L&31 AND RETURN IN HL SHIFTR: XCHG MOV_A,E ANI 31 RZ \ RETURN IF SHIFT BY 0 MOV_D,A CPI 8 JZ SHIFTR3 ORA_H JM SHIFTR1 SHIFTR0: XRA_A MOV_A,H RAR MOV_H,A MOV_A,L RAR MOV_L,A DCR_D JNZ SHIFTR0 RET SHIFTR1: STC MOV_A,H RAR MOV_H,A MOV_A,L RAR MOV_L,A DCR_D JNZ SHIFTR1 RET SHIFTR3: \ SPECIAL CASE - SHIFT BY 8 MOV_L,H ORA_H JM SHIFTR4 MVI_H, 0 RET SHIFTR4: MVI_H, #FF RET
RES1 DW 0 RES2 DW 0 RES3 DW 0 RES4 DW 0 RES5 DW 0 RES6 DW 0
STRN DB #0D,#0A,'.',#0D,#0A,'.',#0D,#0A,0 STR1 DB #1F,"#1234>>#"
| | | | |
Новый выхлоп эмулятора с замером тактов и вычисленными значениями для N от 0 до 32: TEST1.OUT Обновлённый эксель:
|
23 Jul 2024 19:06 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 23285 Location: Silicon Valley
|
На самом деле сдвиги от 16 до 31 бесполезны - там результат заведомо известен (#0000 или #FFFF). От 9 до 15 тоже можно ускорить прикладывая к оставшемуся байту - должно быть быстрее, но дополнительные проверки могут ещё сильнее замедлить сдвиги на небольшое количество бит...
|
23 Jul 2024 21:08 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 23285 Location: Silicon Valley
|
Исправил косяк в != поставив SUB вместо второго CMP, чтобы регистр A обнулился, если половинки равны, а то у меня если сравнивать одинаковые ненулевые числа меньше 256, то подпрограмма ошибочно считала, что они неравны...
|
24 Jul 2024 09:49 |
|
|
shiny
Maniac
Joined: 14 Oct 2023 06:59 Posts: 235
|
Это код для 16бит? А он прокатит в случае A>0,B<0(не регистры, а переменные)?
_________________ uselessretro.blogspot.com
|
24 Jul 2024 20:34 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 23285 Location: Silicon Valley
|
Да - сравниваются HL и взятый со стека DE Если старшие байты не равны, то оно сразу на %l1 уйдёт - после первого CMP
|
24 Jul 2024 21:04 |
|
|
shiny
Maniac
Joined: 14 Oct 2023 06:59 Posts: 235
|
А, это сравнение, не определил спросонья(: Я как-то раз бился с кодом и подсмотрел у HitechC: вышло | | | | Code: loc_80F7: ; CODE XREF: sub_80F4+46j ld (ix+0FEh), 81h ; 'Ѓ' ld (ix+0FFh), 0FFh ; xm=-127 ld (ix+0FCh), 60h ; '`' ld (ix+0FDh), 0 ; ym=96 ld e, (ix+0FEh) ld d, (ix+0FFh) ld l, (ix+0FCh) ld h, (ix+0FDh) call sub_813D ; if (xm>ym) xm=-xm; jp p, loc_812B ld e, (ix+0FEh) ; xm=-xm ld d, (ix+0FFh) ld hl, 0 or a sbc hl, de ld (ix+0FEh), l ld (ix+0FFh), h
loc_812B: ; CODE XREF: sub_80F4+22j ld sp, ix pop ix ret ; ---------------------------------------------------------------------------
loc_8130: ; CODE XREF: sub_80F4j push ix ld ix, 0 add ix, sp push bc push bc jp loc_80F7 ; End of function sub_80F4
; =============== S U B R O U T I N E =======================================
sub_813D: ; CODE XREF: sub_80F4+1Fp ld a, h xor d jp m, loc_8145 sbc hl, de ret ; ---------------------------------------------------------------------------
loc_8145: ; CODE XREF: sub_813D+2j ld a, h and 80h ; 'Ђ' sbc hl, de inc a ret
| | | | |
_________________ uselessretro.blogspot.com
|
24 Jul 2024 21:13 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 23285 Location: Silicon Valley
|
вот тоже самое у меня после препроцессора: скомпилированное в байткод RobbyVM: оттранслируется в ассемблер i8080: | | | | Code: \ Generated by ROBBYCC v2.0.2 (Jul 18 2024) \ Part of nedoPC SDK, see http://www.nedopc.org/nedopc/SDK
ORG 0 @CODE EQU 0 @BASE EQU 1024 @REGS EQU #0444 @REG_X EQU #0444 @REG_Y EQU #0446 \REG_D @REG_N EQU #044A \REG_K @REG_R EQU #044E @REG_T EQU #0450 \REG_E \REG_M \REG_I @REG_A EQU #0458 @REG_B EQU #045A @REG_C EQU #045C \REG_P @REG_L EQU #0460 \REG_S @RAND EQU 0 JMP STARTUP \ DATA _B_OPTS DB 0 _L_FONT DW 0 _L_SIZE DW 0 _L_CODE DW @CODE _L_BASE DW @BASE _L_REGS DW @REGS _L_OSTK DW 0 DB "[NEDOPC SDK BIN]" PROCSYS DB 16 DUP(0) \ PROCESSOR/SYSTEM ID TILES: \ TODO: move tiles here CHX DB 0 CHY DB 0 CHS DB 4 CHB DB 0 _NPLANE DW 0 _ANGLE DB 0 _COLOR DB 0 _CURX DB 0 _CURY DB 0 _SAYX DB 0 _SAYY DB 0 _SAYC DB 0 _ATRS DB 0 \ CODE STARTUP: \ INIT SYSTEM CALL INIT \ COMMON INIT CALL _STD_INIT \ SAVE OLD SP LXI_H, 0 DAD_SP SHLD _L_OSTK \ SET NEW SP LHLD _L_REGS SPHL \ EXECUTE CODE CALL _START \ RESTORE OLD SP LHLD _L_OSTK SPHL RET _START: \ *0x20 %a1 %m2 _j0000: LHLD _L_BASE LXI_D, #0000 DAD_D DAD_D PUSH_H LXI_H, #FF81 POP_D XCHG MOV_M,E INX_H MOV_M,D \ *0x20 %a1 %m2 _j0007: LHLD _L_BASE LXI_D, #0001 DAD_D DAD_D PUSH_H LXI_H, #0060 POP_D XCHG MOV_M,E INX_H MOV_M,D \ *0x40 _j000E: \ 0xF5 PUSH_H LXI_H, #FF0E \ 0xF5 PUSH_H LXI_H, #0000 \ 0xF3 MVI_A, #FF CMP_H JNZ _l0001 \ REGISTER CALL _R_GET JMP _l0002 _l0001: \ VARIABLE CALL _B_GET _l0002: \ 0xF5 PUSH_H LXI_H, #0001 \ 0xF3 MVI_A, #FF CMP_H JNZ _l0003 \ REGISTER CALL _R_GET JMP _l0004 _l0003: \ VARIABLE CALL _B_GET _l0004: \ 0x92 POP_D MOV_A,E SUB_L MOV_L,A MOV_A,D SBB_H MOV_H,A ORA_L JZ _l0006 MOV_A,H ANA_A JM _l0005 LXI_H, #FFFF JMP _l0006 _l0005: LXI_H, 0 _l0006: \ 0xF4 POP_D XCHG MVI_A, #FF CMP_H JNZ _l0007 \ REGISTER CALL _R_SET JMP _l0008 _l0007: \ VARIABLE CALL _B_SET _l0008: POP_H \ *0x42 0x01 0x0E 0xFF 0x00 %w1 _j001D: LHLD @REG_L MOV_A,H ORA_L JZ _j002F \ *0x40 _j0024: \ 0xF5 PUSH_H LXI_H, #0000 \ 0xF5 PUSH_H LXI_H, #0000 \ 0xF3 MVI_A, #FF CMP_H JNZ _l0009 \ REGISTER CALL _R_GET JMP _l0010 _l0009: \ VARIABLE CALL _B_GET _l0010: \ 0xE0 MOV_A,H CMA MOV_H,A MOV_A,L CMA MOV_L,A INX_H \ 0xF4 POP_D XCHG MVI_A, #FF CMP_H JNZ _l0011 \ REGISTER CALL _R_SET JMP _l0012 _l0011: \ VARIABLE CALL _B_SET _l0012: POP_H \ *0x33 _j002F: RET \ *0xFF _j0030:
+/home/shaos/src/SDK-work/LIB/I8080/_STD +/home/shaos/src/SDK-work/LIB/I8080/NULL +/home/shaos/src/SDK-work/LIB/I8080/_CLIB +/home/shaos/src/SDK-work/LIB/I8080/_VARS +/home/shaos/src/SDK-work/LIB/I8080/NULL_
| | | | |
надо подумать как к переменным побыстрее обращаться...
|
25 Jul 2024 00:22 |
|
|
shiny
Maniac
Joined: 14 Oct 2023 06:59 Posts: 235
|
Аж голове больно (: Что-то я не врублюсь - тут сравнение на равенство?
_________________ uselessretro.blogspot.com
|
25 Jul 2024 03:37 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 23285 Location: Silicon Valley
|
У меня так: Сначала вычитаем HL (второй аргумент) из DE (первый аргумент вынутый из стека), потом сравниваем с нулём - если равно, то ответ 0, а если неравно, то проверяем знак старшего байта результата вычитания - если минус, то ответ 0, а если плюс, то ответ -1 (TRUE) P.S. В варианте для Z80 побайтное вычитание заменится на
|
25 Jul 2024 08:59 |
|
|
shiny
Maniac
Joined: 14 Oct 2023 06:59 Posts: 235
|
Кстати, а в библиотеке не завалялось byte reverse? Просто взглянуть
_________________ uselessretro.blogspot.com
|
25 Jul 2024 09:58 |
|
|
Who is online |
Users browsing this forum: No registered users and 0 guests |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot post attachments in this forum
|
|