OberonCore https://forum.oberoncore.ru/ |
|
Оберон-07: вопросы реализации https://forum.oberoncore.ru/viewtopic.php?f=115&t=6352 |
Страница 3 из 5 |
Автор: | Илья Ермаков [ Воскресенье, 24 Февраль, 2019 21:49 ] |
Заголовок сообщения: | Re: Оберон-07: вопросы реализации |
Ну такую штуку можно как-то ещё решить окружением. Например, генерация модуля с такими данными из ресурсного файла. |
Автор: | Oleg N. Cher [ Воскресенье, 24 Февраль, 2019 23:31 ] |
Заголовок сообщения: | Re: Оберон-07: вопросы реализации |
Илья Ермаков писал(а): Например, генерация модуля с такими данными из ресурсного файла. И чего будут представлять собой эти данные в коде? Поэлементное присваивание? Тоже UUDecode("Data")? В таком решении сразу три вида потерь памяти: копия в коде, избыток за счёт символьного кодирования, копия в данных. А должна быть только копия в данных.Кстати, я бы ещё поспорил за присутствие LOOP/EXIT и RETURN из середины процедур. Для мк это может быть ценно хотя бы из соображений производительности. Господа, я загрустил, поняв, что решить RorLong средствами КП красиво не получится. И родил такое решение: Код: PROCEDURE [code] rorlong (x: LONGINT; n: INTEGER): LONGINT 059H, (* POP ECX *) 083H, 0E1H, 03FH, (* AND ECX, 0x3F *) 089H, 0C6H, (* MOV ESI, EAX *) 089H, 0D7H, (* MOV EDI, EDX *) 00FH, 0ADH, 0D6H, (* SHRD ESI, EDX, CL *) 0D3H, 0EFH, (* SHR EDI, CL *) 053H, (* PUSH EBX *) 031H, 0DBH, (* XOR EBX, EBX *) 0F6H, 0C1H, 020H, (* TEST CL, 0x20 *) 00FH, 045H, 0F7H, (* CMOVNE ESI, EDI *) 00FH, 045H, 0FBH, (* CMOVNE EDI, EBX *) 0BBH, 040H, 000H, 000H, 000H, (* MOV EBX, 0x40 *) 029H, 0CBH, (* SUB EBX, ECX *) 088H, 0D9H, (* MOV CL, BL *) 00FH, 0A5H, 0C2H, (* SHLD EDX, EAX, CL *) 0D3H, 0E0H, (* SHL EAX, CL *) 031H, 0DBH, (* XOR EBX, EBX *) 0F6H, 0C1H, 020H, (* TEST CL, 0x20 *) 00FH, 045H, 0D0H, (* CMOVNE EDX, EAX *) 00FH, 045H, 0C3H, (* CMOVNE EAX, EBX *) 05BH, (* POP EBX *) 00BH, 0C6H, (* OR EAX, ESI *) 00BH, 0D7H; (* OR EDX, EDI *) PROCEDURE RorLong* (x: LONGINT; n: INTEGER): LONGINT; BEGIN ASSERT((0 <= n) & (n <= 63)); RETURN rorlong(x, n) END RorLong; На этом вопрос снят. У меня ещё вопрос про реализацию PACK и UNPK. Описание крайне скупое в доках. Как они вообще могут выглядеть в виде алгоритма? |
Автор: | albobin [ Понедельник, 25 Февраль, 2019 09:35 ] |
Заголовок сообщения: | Re: Оберон-07: вопросы реализации |
Oleg N. Cher писал(а): У меня ещё вопрос про реализацию PACK и UNPK. Описание крайне скупое в доках. Как они вообще могут выглядеть в виде алгоритма? Не смотрели на IEEE 754, в частности на: https://ru.wikipedia.org/wiki/%D0%A7%D0 ... 1%82%D0%B8 PS. Сам-то я, давече, "слегка", на 1 бит, лажанулся про где лежит порядок числа. |
Автор: | Oleg N. Cher [ Вторник, 26 Февраль, 2019 11:33 ] |
Заголовок сообщения: | Re: Оберон-07: вопросы реализации |
Оптимизированный вариант RorLong: Код: PROCEDURE [code] rorlong(x: LONGINT; n: INTEGER): LONGINT 059H, (* POP ECX *) 089H, 0C6H, (* MOV ESI, EAX *) 089H, 0D7H, (* MOV EDI, EDX *) 00FH, 0ADH, 0D6H, (* SHRD ESI, EDX, CL *) 0D3H, 0EFH, (* SHR EDI, CL *) 0F6H, 0C1H, 020H, (* TEST CL, 20H *) 074H, 002H, (* JZ SHORT L1 *) 087H, 0F7H, (* XCHG ESI, EDI *) 0F6H, 0D9H, (* L1: NEG CL *) 00FH, 0A5H, 0C2H, (* SHLD EDX, EAX, CL *) 0D3H, 0E0H, (* SHL EAX, CL *) 0F6H, 0C1H, 020H, (* TEST CL, 20H *) 074H, 001H, (* JZ SHORT L2 *) 092H, (* XCHG EAX, EDX *) 00BH, 0C6H, (* L2: OR EAX, ESI *) 00BH, 0D7H; (* OR EDX, EDI *) Коллеги, что скажете насчёт важности контролировать переполнение при логических сдвигах влево? Переполнение в арифметических сдвигах ловить смысл есть. Ofront+ ловит его при константных аргументах, а BlackBox даже в рантайме. В циклических сдвигах переполнений быть не может. Остаются логические сдвиги. Это не очень понятный момент, но в Обероне-07 такой сдвиг присутствует в языке, то есть, сначала Вирт утверждает, что целый тип — абстрактный, и прикладному программисту не обязательно знать как устроено хранение чисел. Но как только логический сдвиг добавлен в язык — программисту уже требуется знать, что бит знака хранится в старшем разряде, что отрицательные числа хранятся в дополнительном коде и т.д. Получается, выдвинули тезис "числа это не биты", потом радостно его сломали и начали битики двигать. А вот в КП эти сдвиги там, где им и положено быть — в SYSTEM. Ну да это так, риторика. Но, поскольку я не понимаю смысла присутствия логического сдвига в языке, то ещё труднее мне понять, нужно ли ловить переполнения таких сдвигов? Выскажите, пожалуйста, ваше мнение. |
Автор: | Trurl [ Вторник, 26 Февраль, 2019 11:43 ] |
Заголовок сообщения: | Re: Оберон-07: вопросы реализации |
А зачем делать сдвиги для LONGINT? Этого же нет в языке, да и смысла в них особо нет. |
Автор: | Oleg N. Cher [ Вторник, 26 Февраль, 2019 11:45 ] |
Заголовок сообщения: | Re: Оберон-07: вопросы реализации |
Мне даже в Обероне-07 нужна поддержка типа SYSTEM.ADRINT, а он может быть 64-битным. Любой реализатор Оберона-07 сталкивается с тем, что ему предлагают накрепко привязать разрядность адресного типа к INTEGER. Я не считаю, что это такая уж хорошая идея. Поэтому INTEGER отдельно, SYSTEM.ADRINT отдельно. |
Автор: | Comdiv [ Вторник, 26 Февраль, 2019 13:20 ] |
Заголовок сообщения: | Re: Оберон-07: вопросы реализации |
Oleg N. Cher писал(а): Мне даже в Обероне-07 нужна поддержка типа SYSTEM.ADRINT, а он может быть 64-битным. И биты вращать адресу тоже нужно? Вы, ведь, знаете, что в общем случае адрес - это не обязательно индекс в массиве общей памяти?
|
Автор: | Trurl [ Вторник, 26 Февраль, 2019 14:15 ] |
Заголовок сообщения: | Re: Оберон-07: вопросы реализации |
Если адрес 64-битный, то и процессор, скорее всего, тоже. Но тогда реализация сдвигов довольно проста. |
Автор: | Oleg N. Cher [ Вторник, 26 Февраль, 2019 14:47 ] |
Заголовок сообщения: | Re: Оберон-07: вопросы реализации |
Хорошо, я попробую иначе сформулировать. Мне нужна единая разрядность INTEGER на 32-х и 64-битных архитектурах, чтобы писать код без оглядки на разрядность системы. С той же целью нужна единостильная работа с адресами через тип SYSTEM.ADRINT. Посему да, поддержку сдвигов для 64-х бит нужно заложить, она тут сама просится. Также нужна возможность даже из Оберона-07 работать с системным типом SYSTEM.INT64. Ещё я не исключаю возможность опционально задавать для Оберона-07 разрядность INTEGER. А ещё я делаю реализацию Ofront+ для BlackBox, а он чисто 32-битный, как вы знаете. На самом Ofront+ с циклическими сдвигами проблем вообще нет — ROR сделан через SYSTEM.ROT. |
Автор: | Kemet [ Среда, 27 Февраль, 2019 06:37 ] |
Заголовок сообщения: | Re: Оберон-07: вопросы реализации |
В А2 есть реализации, и в них есть ссылка на хороший папир Код: PROCEDURE RorH*(l: HUGEINT; r: LONGINT): HUGEINT; CODE{SYSTEM.i386} PUSH ECX ; taken from "Software Optimization Guide for AMD64 Processors" MOV ECX,[EBP+r+0] MOV EAX,[EBP+l+0] MOV EDX,[EBP+l+4] ; EBX (initially=EAX) -> EDX -> EAX ; Shift EDX:EAX right, shift count in ECX (count ; applied modulo 64). MOV EBX,EAX SHRD EAX,EDX,CL ; First apply shift count. SHRD EDX,EBX,CL ; mod 32 to EDX:EAX TEST ECX,32 ; Need to shift by another 32? JZ rshiftdone ; No, done. MOV EBX,EAX SHRD EAX,EDX,CL SHRD EDX,EBX,CL rshiftdone: POP ECX END RorH; Контролировать переполнение смысла нет, так как такого контроля нет и в арифметических операциях, но флаги должны быть установлены, чтобы иметь потенциальную возможность и следуя однообразию и здравому смыслу. По этой же причине ASSERT для диапазона не нужен |
Автор: | Oleg N. Cher [ Среда, 27 Февраль, 2019 12:30 ] |
Заголовок сообщения: | Re: Оберон-07: вопросы реализации |
Переписал для BlackBox: Код: PROCEDURE [code] rorlong(x: LONGINT; n: INTEGER): LONGINT (* taken from "Software Optimization Guide for AMD64 Processors" *) (* ESI (initially=EAX) -> EDX -> EAX *) (* Shift EDX:EAX right, shift count in ECX (count applied modulo 64). *) 059H, (* POP ECX *) 08BH, 0F0H, (* MOV ESI, EAX *) 00FH, 0ADH, 0D0H, (* SHRD EAX, EDX, CL ; First apply shift count. *) 00FH, 0ADH, 0F2H, (* SHRD EDX, ESI, CL ; mod 32 to EDX:EAX *) 0F6H, 0C1H, 020H, (* TEST CL, 32 ; Need to shift by another 32? *) 074H, 008H, (* JZ SHORT done ; No, done. *) 08BH, 0F0H, (* MOV ESI, EAX *) 00FH, 0ADH, 0D0H, (* SHRD EAX, EDX, CL *) 00FH, 0ADH, 0F2H (* SHRD EDX, ESI, CL *) ; (* done: *) Код точно рабочий? Я проверил. Он даёт для ROR(1, 1) результат F333333333333334, для ROR(1, 2) то же самое. Kemet писал(а): Контролировать переполнение смысла нет, так как такого контроля нет и в арифметических операциях В Ofront'е+ при вычислении константных значений такой контроль есть. А в BlackBox он встречается и в рантайме (в ASH, в частности).
|
Автор: | Kemet [ Среда, 27 Февраль, 2019 14:15 ] |
Заголовок сообщения: | Re: Оберон-07: вопросы реализации |
А как в ББ параметры передаются? |
Автор: | Kemet [ Среда, 27 Февраль, 2019 14:31 ] |
Заголовок сообщения: | Re: Оберон-07: вопросы реализации |
Oleg N. Cher писал(а): Код точно рабочий? Я проверил. Он даёт для ROR(1, 1) результат F333333333333334, для ROR(1, 2) то же самое. Рабочий Код: PROCEDURE Do*; VAR x: HUGEINT; BEGIN x := 1; TRACE( SYSTEM.VAL( SET64, x )); x := ROR( x, 1); TRACE( SYSTEM.VAL( SET64, x )); x := ROR( x, 1); TRACE( SYSTEM.VAL( SET64, x )); x := ROR( x, 1); TRACE( SYSTEM.VAL( SET64, x )); x :=1; x := ROR( x, 3); TRACE( SYSTEM.VAL( SET64, x )); END Do; Вывод {P cpuid= 0, pid= 9360 Test.Do@84:SYSTEM.VAL(SET64, x)= {0}; } {P cpuid= 0, pid= 9360 Test.Do@136:SYSTEM.VAL(SET64, x)= {63}; } {P cpuid= 0, pid= 9360 Test.Do@188:SYSTEM.VAL(SET64, x)= {62}; } {P cpuid= 0, pid= 9360 Test.Do@240:SYSTEM.VAL(SET64, x)= {61}; } {P cpuid= 0, pid= 9360 Test.Do@302:SYSTEM.VAL(SET64, x)= {61}; } |
Автор: | Oleg N. Cher [ Среда, 27 Февраль, 2019 15:48 ] |
Заголовок сообщения: | Re: Оберон-07: вопросы реализации |
Kemet писал(а): А как в ББ параметры передаются? Цитата: Процедуры в машинных кодах позволяют использовать специальные последовательности машинных команд, которые не генерируются компилятором. Для их объявления используется следующий специальный синтаксис: ProcDecl = PROCEDURE "[" SysFlag "]" IdentDef [FormalPars] [ConstExpr {"," ConstExpr}] ";". Список констант, объявленный с процедурой, интерпретируется как строка байт и вставляется непосредственно в код («in-line»), из которого вызвана процедура. Если присутствует список параметров, фактические параметры загружаются в стек справа налево. Однако первый параметр записывается в регистр. Если тип первого параметра REAL или SHORTREAL, то он записывается в верхний регистр для чисел с плавающей точкой. Иначе параметр (или в случае VAR/IN/OUT-параметра — его адрес) записывается в EAX. Для процедур-функций ожидается, что и результат сохраняется в верхнем регистре с плавающей точкой или в EAX, в зависимости от его типа. Будьте осторожны, когда используете регистры в кодовых процедурах. В общем, можно использовать регистры ECX, EDX, ESI и EDI. Параметры должны удаляться со стека процедурой. Примеры PROCEDURE [code] Sqrt (x: REAL): REAL (* Math.Sqrt *) 0D9H, 0FAH; (* FSQRT *) PROCEDURE [code] Erase (adr, words: INTEGER) (* erase memory area *) 089H, 0C7H, (* MOV EDI, EAX *) 031H, 0C0H, (* XOR EAX, EAX *) 059H, (* POP ECX *) 0F2H, 0ABH; (* REP STOS *) Для нашего случая PROCEDURE {code} rorlong (x: LONGINT; n: INTEGER): LONGINT; аргумент x передаётся в EDX:EAX, аргумент n мы снимаем со стека командой POP ECX, а результат ожидается в EDX:EAX. Также в варианте для BlackBox я использовал регистр ESI вместо EBX, потому что EBX нужно было бы сохранять, а ESI не надо. |
Автор: | Oleg N. Cher [ Среда, 27 Февраль, 2019 17:43 ] |
Заголовок сообщения: | Re: Оберон-07: вопросы реализации |
Kemet, этот код точно нерабочий для n >= 32, можете подавать баг-репорт. Смотрите. Если первый сдвиг производится на (n mod 32) битов, а там нужен был сдвиг на {0..63}, то второй сдвиг надо делать ровно на 32 бита, т.е. просто поменять регистры местами. А он опять делается на (n mod 32) битов. Вот рабочий вариант: Код: PROCEDURE [code] rorlong(x: LONGINT; n: INTEGER): LONGINT
059H, (* POP ECX *) 08BH, 0F0H, (* MOV ESI, EAX *) 00FH, 0ADH, 0D0H, (* SHRD EAX, EDX, CL *) 00FH, 0ADH, 0F2H, (* SHRD EDX, ESI, CL *) 0F6H, 0C1H, 020H, (* TEST CL, 32 *) 074H, 001H, (* JZ SHORT done *) 092H (* XCHG EAX, EDX *) ; (* done: *) |
Автор: | Kemet [ Четверг, 28 Февраль, 2019 06:15 ] |
Заголовок сообщения: | Re: Оберон-07: вопросы реализации |
XCHG там не подходит, потому что не устанавливает флаги, которые устанавливаются в 64-битном режиме. |
Автор: | Oleg N. Cher [ Четверг, 28 Февраль, 2019 07:51 ] |
Заголовок сообщения: | Re: Оберон-07: вопросы реализации |
Очень даже подходит. Зачем нужно устанавливать эти флаги? Кто-то после вызова процедуры будет полагаться на них? Может есть негласные правила, как их надо выставить правильно? Бред же. Коллеги, кто может прояснить вопрос: зачем BlackBox требует сохранять регистр общего назначения EBX? Как именно он его использует? Я предполагаю, что в документации просто забыли упомянуть EBX как разрешённый для изменения регистр. Oleg N. Cher писал(а): Код точно рабочий? Я проверил. Он даёт для ROR(1, 1) результат F333333333333334 А вот это, оказывается, было вызвано багом в калькуляторе Windows 7. Попробуйте вставить число -9223372036854775808 и сконвертить в Hex 8 байт. Он выдаёт: F333333333333334. Если вбить в Hex вручную 8000000000000000 и сконвертить обратно в Dec, будет -9223372036854775808. Мда уж.
|
Автор: | SovietPony [ Пятница, 01 Март, 2019 07:06 ] |
Заголовок сообщения: | Re: Оберон-07: вопросы реализации |
Oleg N. Cher писал(а): Коллеги, кто может прояснить вопрос: зачем BlackBox требует сохранять регистр общего назначения EBX? Как именно он его использует? Я предполагаю, что в документации просто забыли упомянуть EBX как разрешённый для изменения регистр. Он используется как статическая свзязь. Т.е. используются локальными процедурами. |
Автор: | Kemet [ Суббота, 02 Март, 2019 17:44 ] |
Заголовок сообщения: | Re: Оберон-07: вопросы реализации |
Oleg N. Cher писал(а): Очень даже подходит. Всё-же, я думаю, что после XCHG нужно поставить что-то типаКод: TEST EDX, 80000000H
JZ done STC |
Автор: | Oleg N. Cher [ Воскресенье, 03 Март, 2019 11:17 ] |
Заголовок сообщения: | Re: Оберон-07: вопросы реализации |
Зачем? Вам так спокойнее? Никогда не видел такой практики, чтобы ценилось непонятное значение флагов непонятно после какой операции. Которых там может быть тьма. Kemet, но чисто для Вас я поменял местами XCHG и SHRD. Код: PROCEDURE [code] rorlong (x: LONGINT; n: INTEGER): LONGINT
059H, (* POP ECX *) 0F6H, 0C1H, 020H, (* TEST CL, 32 *) 074H, 001H, (* JZ SHORT L1 *) 092H, (* XCHG EAX, EDX *) 08BH, 0F0H, (* L1: MOV ESI, EAX *) 00FH, 0ADH, 0D0H, (* SHRD EAX, EDX, CL *) 00FH, 0ADH, 0F2H; (* SHRD EDX, ESI, CL *) |
Страница 3 из 5 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |