Я в этом не шарю
4 / 4 / 3
Регистрация: 03.09.2014
Сообщений: 191
|
|||||||||||
1 | |||||||||||
Проблемы со смещением бит (<< >>)27.07.2019, 21:56. Показов 3123. Ответов 15
Метки нет (Все метки)
Архитектура m68k
Версия языка C++11 Платформа разработки Linux Компилятор m68k-linux-gnu-g++-8 Флаги -m68000 -Wall -fno-builtin Прикол в том, что компилятор генерирует мусор всякий раз, когда я пишу смещение бит на колличество больше 7. По логике вещей архитектура не поддерживает смещение больше чем на 8 бит, поэтому компилятор должен генерировать 2 комманды смещения бит: одну на максимальное (8) число бит и одну на остаток. Но почему-то даже смещение на 8 бит уже генерирует мусор. Пример:
А то даже в листинге пишет невразумительно (строка 13da):
покопался в коммандах и вот что обнаружил. если написать -mcpu=68000 -march=68000 -Wall -fno-builtin то компилятор выдает lto1: warning: -mcpu=68020 conflicts with -march=68000 также в списке сокращений команд написано:
0
|
27.07.2019, 21:56 | |
Ответы с готовыми решениями:
15
Система со смещением на 128 Вставка со смещением Распознавание букв со смещением Удаление столбцов со смещением |
27.07.2019, 22:24 | 2 |
lto - это link-time optimization, включаемое по опции -flto. Видимо, в компиляцию попадает промежуточное представление из какого-то объектного файла, скомпилиенного в режиме -mcpu=68020 (т.е. более старший режим, чем тот, который задан в командной строке). Убери опцию -flto, если это тебе не нужно
А ты уверен, что код из того места? "lsrl #1,%d0" навскидку означает "сдвиг влево на 1 бит" Лучше напиши минимально короткий пример и покажи ассемблерный файл. Компилятор запускать как "gcc t.c -S", в итоге построится ассемблерный файл t.s Добавлено через 3 минуты А не... lsrl наверное "logical shift right для формата l". Только почему сдвиг делается на 1 бит, а не на 9? Но всё равно напиши полный короткий пример на Си и полный ассемблерный файл Добавлено через 8 минут Вот такой тест на Си C unsigned int a = 15; unsigned int b = 16; void foo (void) { asm ("---"); a >>= 4; asm ("---"); b >>= 9; asm ("---"); }
0
|
Я в этом не шарю
4 / 4 / 3
Регистрация: 03.09.2014
Сообщений: 191
|
|
27.07.2019, 22:25 [ТС] | 3 |
помог -mno-bitfield
0
|
27.07.2019, 22:34 | 4 |
Сообщение было отмечено Segaman как решение
Решение
https://gcc.gnu.org/onlinedocs... x0-Options
-mbitfield Do use the bit-field instructions. The -m68020 option implies -mbitfield. This is the default if you use a configuration designed for a 68020. Судя по всему, речь идёт о какой-то специфической операции в m68020, которой нет в m68000. Собственно, поэтому дизассемблер и не смог в этом месте ничего нормально написать, т.к., предположительно, он работал в режиме m68000, но из-за режима -flto у тебя в исполняемый файл просочился код от m68020 Думается, это говорит о том, что -mno-bitfield чисто затыкает проблему в твоём конкретном случае. Рано или поздно ты споткнёшься о другое аналогичное место. Разбирайся, откуда у тебя берётся опция -flto. Компилятор не зря выдавал тебе предупреждение
1
|
Я в этом не шарю
4 / 4 / 3
Регистрация: 03.09.2014
Сообщений: 191
|
||||||
27.07.2019, 22:51 [ТС] | 5 | |||||
Evg, спасибо.
убрал из LINKERDEFS и все стало нормально собираться.
0
|
27.07.2019, 23:10 | 6 |
Все эти опции в LINKERDEFS имели какой-то смысл, только если включен режим -flto, т.к. это опции компилятора, а не линкера. Т.е. они на самом деле передавались в запуск компилятора, который вызывался из-под линкера (так работает режиме -flto). Поэтому все эти опции теперь болтаются мёртвым грузом, их тоже можно удалить
0
|
28.07.2019, 12:19 | 7 |
Да, ещё один момент
Строго говоря, источником проблемы с lto является на сам по себе режим -flto, а то, что в этот режим попадает мешанина из файлов, собранных в режиме -mcpu=m68000 и -mcpu=m68020. В итоге строится код, который номинально помечен как код m68000, но внутри себя содержит инструкции m68020. При запуске на m68020 этот код проблем не вызовет, но при запуске на m68000 сломается. При желании можно во всём этом покопаться и привести всю сборку в такой вид, чтобы всё компилировалось с одним и тем же значением опции -mcpu (или -march). А потом можно будет вернуть режим -flto. Сам по себе режим -flto полезен с точки зрения производительности в случаях, если софтина спроектирована коряво в плане разбития кодов на модули
0
|
Я в этом не шарю
4 / 4 / 3
Регистрация: 03.09.2014
Сообщений: 191
|
|
28.07.2019, 12:25 [ТС] | 8 |
у меня нигде не указан -m68020
откуда он берется вообще? ыходит все же стоит ограничиться -mno-bitfield?
0
|
28.07.2019, 12:46 | 9 |
Предупреждение взялось не просто так. Вероятно, используются какие-то библиотеки, которые собраны в режиме -flto -mcpu=68020. По твоему описанию я не очень понимаю, что у тебя там вообще делается. Может быть так, что у тебя основная программа собирается в режиме 68020 (который, например, включен по умолчанию), а библиотечные коды собраны в режиме -flto 68000. Другими словами, имеет место быть зоопарк и полезно бы его распотрошить
По опции -v в финальной строке линковки с виду до всего докупаться можно. Мне казалось, что там должно быть более-менее очевидно, но в реальности оказалось, что всё довольно сложно. В итоге, если нет понимания, что такое режим -flto и как устроен процесс компиляции, то скорее всего утонешь и имеет смысл забить Я не могу тебе на 100% ответить на этот вопрос, т.к. ставлю диагноз по телефону. То, как вижу проблему я, говорит о том в общем случае это проблему не решит, т.к. источник проблемы в другом месте С другой стороны, если вся проблема сводится к тому, что ты не видишь нормального дизассемблера, но программа работает нормально (т.е. имеется процессор, который реально умеет исполнять операции 68020), то на проблему можно было бы вообще забить. Подобный зоопарк из кодов 68000 и 68020 не вредит железке, которая умеет исполнять и то и другое
0
|
Я в этом не шарю
4 / 4 / 3
Регистрация: 03.09.2014
Сообщений: 191
|
|
28.07.2019, 12:56 [ТС] | 10 |
ну проц при виде непонятной команды от 68020 высыпается в прерывание illegal command, потом возвращается и снова высыпается.
также я не подключаю вообще никаких библиотек, так что даже new и delete не вызвать (не то чтобы они нужны с таким-то объёмом памяти в 64кб я и см все неплохо размечаю) складывается впечатление, что для каких-то файлов не применяются указанные мной опции. я перепроверю Makefile, чтобы там все проставлено было и верну все как было, чтобы убедиться, что проблема была в этом. вообще в интернете кот наплакал инфы по написанию своего Makefile с линковщиками и прочим, хотя тут скорее сказывается моя вражда с гуглом (он никогда не дает мне того, что я прошу у него) по большей части я понатырил из разных форумов всяких вещей, запихал их в Makefile и всё заработало как надо, но видимо не до конца.
0
|
28.07.2019, 13:05 | 11 |
Всё-таки так. Т.е. процессор 68000. Тогда опция -mno-bitfield в общем случае не поможет. Проблема, судя по всему, растёт из того, что какие-то коды собираются в режиме 68020. Это может быть, например, ещё и в тех случаях, если компилятор по умолчанию взводит режим 68020 (т.е. в логах сборки строки "68020" нет, но такой режим всё равно есть). Если используются какие-то коды, которые компилируешь не ты, а берёшь их в виде готового бинарника (любые объектные файлы или библиотеки, в том числе и те, которые подключает сам компилятор), то проблема может лезть в том числе и оттуда
Тот факт, что опция -mno-bitfield тебе помогла, говорит о том, что те файлы, в компиляцию которых попала опция -mno-bitfield, изначально собирались в режиме 68020. Ну может быть не все файлы, но по крайней мере хотя бы один Добавлено через 57 секунд Для порядку покажи весь лог сборки, может быть оттуда удастся что-то понять. Но для этого сначала нужно сделать полную очистку проекта, чтобы он собирался с полного нуля и в логе было засвечено всё
0
|
Я в этом не шарю
4 / 4 / 3
Регистрация: 03.09.2014
Сообщений: 191
|
|
28.07.2019, 16:13 [ТС] | 12 |
Evg, вот весь вывод:
с удаленным -flto добавил DEFAULT_FLAGS к финальной стадии и всё сошлось
0
|
28.07.2019, 18:56 | 13 |
Это не "удалённый -flto", а "удалённый -flto и добавленный -mno-bitfiled"
Тут никакого криминала не видно. К тому же линкер запускается ручками, т.е. никаких левых библиотек быть не должно Тут вообще режим -flto не даёт ничего, т.к. в ручной запуск линкера "m68k-linux-gnu-ld -T etc/md.ld" и в запуск линкера через компилятор "m68k-linux-gnu-g++-8 -n -T etc/md.ld" не подаётся никаких указаний для линковки в режиме -flto Другими словами, я не вижу, почему наличие или отсутствие опции -flto может приводить к разным результатам. И подозреваю, что различие в двух запусках вовсе не в том, есть или нет -flto, а в том, есть или нет -mno-bitfiled По итогу есть только одна идея - это вместо опции -mc68000 попробовать поставить три опции "-march=m68000 -mcpu=m68000 -mtune=m68000" и, соответственно, удалить -flto и -mno-bitfield. Если это ни к чему не приведёт, то заканчивать эксперименты. То, что имеется сейчас, нужно решать вживую, когда можно пощупать каждый объектный файл. А если решать по телефону, то с человеком, который будет понимать, что делается Фраза не говорит ничего, т.к. я не знаю, чему равно DEFAULT_FLAGS и что ты подразумеваешь под "финальной стадией". Лог запуска после этих манипуляций дал бы больше полезной информации
0
|
Я в этом не шарю
4 / 4 / 3
Регистрация: 03.09.2014
Сообщений: 191
|
|
28.07.2019, 19:05 [ТС] | 14 |
Evg,
0
|
28.07.2019, 19:55 | 15 |
Ах ты ж ё... не заметил в логах, что этого не было. Собственно, я ради этого-то и попросил логи, но глаз замылился, пока их с форума читал
Добавлено через 2 минуты А не... я это видел. Мне показалось, что здесь оно не должно было никак повлиять. И выглядит странным, что повлияло Точнее, оно должно было повлиять только в том случае, если бы здесь было -flto, но здесь его нет
0
|
29.07.2019, 08:47 | 16 |
Сообщение было отмечено Segaman как решение
Решение
Давай вкратце объясню, что тут произошло
----- Как было раньше (несколько лет назад). У gcc есть (были) две опции -march и -mcpu. Опция -march задаёт, какую нужно использовать систему команд, т.е. задаёт набор допустимых инструкций, которыми вправе пользоваться компилятор. Опция -mcpu задаёт конкретную модель процессора, под которую надо подстраиваться, т.е. задаёт набор задержек между операциями, который должен выдерживать компилятор Логика двух опций примерно такая. Допустим, есть семейство процессоров П, в котором по очереди были выпущены совместимые процессора П1, П2, П3, П4, П5. Каждый новый процессор обладал более широкой системой команд (т.е. более широкими возможностями). Но при этом каждый процессор имел свои точные задержки. Мы можем задать режим -march=П2 -mcpu=П4. Опция -march=П2 означает, что код будет использовать систему команд П2, т.е. итоговый код сможет работать на процессорах П2, П3, П4, П5, но не сможет работать на процессоре П1. Опция -mcpu=П4 означает, что следует использовать задержки, соответствующие процессору П4. В итоге полученный код будет работать на процессорах П2, П3, П4, П5, но при этом на процессоре П4 он будет работать наиболее эффективно, т.к. именно на этом процессоре все реальные задержки в коде и аппаратуре будут совпадать. На остальных процессорах могут возникать лишние холостые такты Но в реальности в какой-то из ранних версий gcc они переименовали опции. В итоге нынешнее -march совпадает с тем, что написано выше. Но то, что в моём описании описано как -mcpu, в современных версиях теперь называется -mtune. Что теперь означает -mcpu, я не совсем понимаю ----- Вернёмся в сегодняшний день В твоём случае, судя по всему, компилятор по умолчанию работает в режиме -march=m68020 -mcpu=m68020 -mtune=m68020 (последнее нам не интересно, я его буду опускать). Когда ты просто подавал опцию -mc68000, то по описанию (ссылка в посте #4) она эквивалентна -march=m68000. Т.е. у тебя как бы включался режим -march=m68000 -mcpu=m68020. Далее там есть тонкий момент -mcpu=cpu overrides -march=arch if arch is compatible with cpu Похоже на то, что в твоём случае дефолтный режим -mcpu=68020 перебивает опцию командной строки -march=68000 и в итоге компилятор всё равно работает в системе команд 68020, но не 68000, как предполагалось бы, глядя на командную строку. Это и приводит к проблеме. Компилятор строит код 68020, который ломается при запуске на твоём процессоре 68000 Когда вместо одной опции -m68000 ты начал использовать две опции -march=m68000 -mcpu=m68000, то эфект перебития дефолтным режимом пропал и поведение компилятора начало соответствовать тому, что написано в командной строке Однако опции -march/-mcpu/-mtune влияют только на процесс компиляции (на процесс построения кода). На процесс линковки они не должны влиять, т.к. во время линковки не рожается никаких кодов. Исключение составляет режим -flto, который приводит к тому, что во время линковки запускается компилятор для повторной перекомпиляции некоторых модулей. И здесь опции -march/-mcpu берутся из командной строки и подсовываются в компилятор. Собственно, поэтому для меня пост #14 является загадкой. Я не понимаю, как это могло исправить ситуацию. А в таких случаях очень часто возникает ситуация, когда сегодня работает, а завтра перестаёт работать, потому что в реальности случилось не исправление проблемы, а затычка Опция -mno-bitfiled говорит о том, что из системы команд m68020 нельзя использовать какие-то отдельно взятые инструкции. Т.е. использовать кастрированную систему команд m68020. В твоём случае на конкретно твоей программе получилось так, что система команд m68020 за вычетом операций bitfiled привела к тому, что именно в твоём коде остались только операции m68000, а потому код перестал падать. Но если бы компилятор генерировал условную операцию venik, которая есть в m68020, но нет в m68000, то тебе опция -mno-bitfiled не помогла бы. Другими словами, опция -mno-bitfiled выполняла роль затычки в конкретном случае, но не выполняла роль исправления проблемы
1
|
29.07.2019, 08:47 | |
29.07.2019, 08:47 | |
Помогаю со студенческими работами здесь
16
Динамическое выделение со смещением Шифровка и замена со смещением Дифферинциальный сумматор со смещением. Шифрование строки смещением Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |