Сообщение от
Sayman
Я нашел xnx-evo в последнем выпуске evo sdk.
У меня тоже не было проблем с компиляцией.
https://drive.google.com/file/d/0B6X...ew?usp=sharing
В evo.h я прокомментировал некоторые прототипы:
Код:
//заполнение памяти заданным значением
//void memset(void* m,u8 b,u16 len) _naked;
//копирование памяти, области не должны пересекаться
//void memcpy(void* d,void* s,u16 len) _naked;
//генерация 16-битного псевдослучайного числа
//u16 rand16(void) _naked;
//установка цвета бордюра, 0..15
Это имеет смысл в версии 2.9, но приведет к ухудшению кода в новых версиях sdcc. Причина: sdcc теперь попытается встроить несколько строковых функций, включая memset () и memcpy (). Если вы посмотрите на сгенерированный ASM с новой компиляцией, вы увидите, что эти вызовы функций реализованы с помощью ldir, встроенного в код. Определение ваших собственных функций для замены этого ухудшит ситуацию.
Я сделал то же самое для rand (). Я подозреваю, что это лучше реализовано в библиотеке компилятора, но я не проверял, чтобы реализация evo-sdk точно знала. Sdcc теперь использует генератор xars Marsaglia, который работает очень быстро, даже несмотря на то, что он реализован в C. В основном я это сделал, потому что z88dk реализует эту функцию в ASM.
В main.c я изменил некоторые заголовки:
Скрытый текст
This made sense in 2.9 but will result in worse code in newer versions of sdcc. The reason is sdcc will now try to inline several string functions including memset() and memcpy(). If you look at the generated ASM with a new compile you'll see these function calls implemented with ldir inlined in the code. Defining your own functions to replace this will make things worse.
I did the same for rand(). I suspect this is better implemented in the compiler's library but I did not check evo-sdk's implementation to know for sure. sdcc now uses a Marsaglia xor generator which is very fast even though it's implemented in C. Mainly I did it because z88dk implements this function in ASM..
In main.c I changed some of the header includes:
[свернуть]
Код:
//#include <evo.h>
#include <string.h>
#include "evo.h"
Угловые скобки предназначены для заголовков, найденных в системном каталоге. Это не то, где evo.h находится в моих компиляциях, поэтому я изменил это на кавычки. Я также добавил string.h для получения библиотек memset () и memcpy ().
Я не могу скомпилировать бинарный файл, потому что мне придется исправлять остальную часть SDK, чтобы она была совместима с более новой версией sdcc. Но я могу перевести на asm и посмотреть, появляются ли какие-либо ошибки.
Скрытый текст
Angle brackets are for headers found in the system directory. That's not where evo.h is in my compiles so I changed that to quotes. I also added string.h to get the library memset() and memcpy() .
I can't compile to a binary because I'd have to fix up the rest of the SDK to be compatible with a newer version of sdcc. But I can translate to asm and see if any errors pop up.
[свернуть]
sdcc -mz80 -S main.c -D_naked= (~1-2 minutes)
sdcc -mz80 -S --max-allocs-per-node200000 main.c -D_naked= (~14 minutes)
Вы можете выбрать, хотите ли вы быстро компилировать или оптимизировать. В этой программе не так уж много различий, потому что большинство переменных являются статическими. «-Dnaked =» заключается в том, чтобы устранить атрибуты «_naked» во всех функциях C в main.c. Вещи больше не делаются так в new sdcc.
Вы можете увидеть выходные файлы .asm в .zip выше. Беглый осмотр я не обнаружил.
Скрытый текст
You can choose if you want a fast compile or a highly optimized one. In this program there isn't too much difference because most variables are statics. The "-Dnaked=" is to eliminate the "_naked" attributes on all the C functions in main.c. Things are no longer done this way in new sdcc.
You can see the output .asm files in the .zip above. I did not spot any problems with a cursory examination.
[свернуть]
Постоянные какие то "переполнения" у него. Да. Это прекрасный компилятор, очень и очень.
Это потому, что программист допустил ошибку или просто проигнорировал это. Компилятор правильный. Все эти жалобы касаются кода, подобного этому:
Скрытый текст
This is because the programmer has made a mistake or he's simply ignoring this. The compiler is correct. All those complaints are about code similar to this:
[свернуть]
Код:
const u8 levelData1[]={
IMG_PIC1,PAL_PIC1,MUS_LOOP1,85,
9,10,-16,16,
28,10, 16,16,
255
};
Обратите внимание, что это массив символов UNSIGNED. Но программист ставит отрицательные числа там. Эти отрицательные числа представляют собой 16-разрядные целые числа. Например, -16 представляется как 0xffea. Затем компилятор пытается поместить 0xffea в 8-разрядный беззнаковый символ. Он делает все возможное, используя только младший байт и выдавая предупреждение, чтобы сообщить вам, что оно это сделало.
Поэтому все эти предупреждения являются ошибкой программиста. Sdcc прав, чтобы предупредить об этом - такие ошибки часто могут оказаться ошибками. В этом случае это не ошибки.
Немного позже в компиляции вы увидите еще одно предупреждение о потере указателя CONST. Это связано с тем, что программист неявно преобразовал указатель CONST в обычный указатель. Опять же, это предупреждение правильное, и оно испускается, потому что это еще один распространенный тип ошибки. Но в этом случае нет ошибки.
Начинающие могут найти предупреждения, сбивающие с толку или раздражающие, но для опытных они могут быть бесценными для отслеживания трудно найти ошибки. Тот факт, что другие компиляторы не могут сообщать обо всех этих вещах как о предупреждениях, является слабостью этих других компиляторов.
Я сделал ту же компиляцию с zsdcc, но на этот раз zsdcc будет использовать «-reserve-regs-iy», что подразумевается «-clib = sdcc_iy». В результирующем коде есть два места, где z88dk исправляет ошибки в sdcc. В z88dk предпочтительнее использовать «-reserve-regs-iy», потому что это приводит к значительно меньшему коду в целом, когда применяется агрессивный набор гласных z88dk.
Скрытый текст
Notice that this is an UNSIGNED char array. Yet the programmer is putting negative numbers in there. These negative numbers are 16-bit integers. For example, -16 is represented as 0xffea . The compiler then tries to fit 0xffea into an 8-bit unsigned char. It does its best by using only the least significant byte and emitting an warning to let you know it has done so.
So all those warnings are the fault of the programmer. sdcc is right to warn about it -- these types of errors can often turn out to be bugs. In this case these aren't bugs.
A little later in the compile you will see another warning about a pointer losing CONST. This is because the programmer has implicitly casted from a CONST pointer to a regular pointer. Again, this warning is correct and it is emitted because this is another common type of bug. But in this case there is no bug.
Beginners may find the warnings disconcerting or annoying but for the experienced they can be invaluable for tracking down difficult to find bugs. The fact that other compilers may not report these things as warnings is a weakness of those other compilers.
I did the same compile with zsdcc but this time zsdcc will use "--reserve-regs-iy" which is implied by "-clib=sdcc_iy". In the resulting code there are two places where z88dk fixes up bugs in sdcc. In z88dk it's preferable to use "--reserve-regs-iy" because it leads to much smaller code in general when z88dk's aggressive peephole set is applied.
[свернуть]
zcc +z80 -vn -a -SO3 -clib=sdcc_iy main.c -D_naked= --c-code-in-asm (~1-2 minutes)
zcc +z80 -vn -a -SO3 -clib=sdcc_iy --max-allocs-per-node200000 main.c -D_naked= --c-code-in-asm (~16 minutes)
(Целевой компьютер «+ z80» не имеет большого значения для перевода в .asm. Это повлияет только на то, какие заголовки доступны из библиотеки).
(The target machine "+z80" does not matter much for a translation to .asm. It will only affect what headers are available from the library).
...
чё-то анреал какой-то. воткнул ключ --max-allocs-per-node200000 и пипец, он завис чтоли, этот sdcc? уже минут 10 чёто мухрюет там... ощущение. что я сижу на древней 286, а не на 8ми ядернике. это типо прикольно, таким компилятором пользоваться))))
Да, это медленно. Команда sdcc не рассматривала лучшие структуры данных в своей первой попытке с этим новым генератором кода. Имейте в виду, что то, что делает sdcc за кулисами, гораздо сложнее, чем, скажем, HTC.
Просто уменьшите число «max-allocs-per-node» или вообще исключите этот параметр (по умолчанию используется «max-allocs-per-node3000»). В этой программе это не имеет большого значения.
Я использую 200000 для релизов и когда я ищу способы улучшить вывод кода. Для меня вполне приемлема длинная сборка для выпуска. Для развития вы можете пойти ниже. Я не думаю, вместо этого я правильно разбиваю проект на множество исходных файлов и использую make-файл, так что только файлы, которые я изменяю, перекомпилируются. Таким образом, количество кода, который компилятор должен пережевывать, меньше и вывод генерируется быстрее.
Кстати, Philip at sdcc использует 1000000, когда он запускает тесты. Я не могу использовать этот номер на этом ноутбуке, так как для больших программ он будет исчерпан. Я также считаю, что разница не слишком велика между 200000 и 1000000. Из-за этого мы принимаем 200000 в качестве магического числа и фокусируем усилия на улучшении вывода кода для этого уровня. Я думаю, что Fuzix принял наш номер 200000 тоже, но в прежние времена это было 500000, я верю.
Скрытый текст
Yes it is slow. The sdcc team did not consider better data structures in their first attempt with this new code generator. Keep in mind that what sdcc is doing behind the scenes is much more sophisticated than what, say, HTC is doing.
Just reduce the "max-allocs-per-node" number or eliminate the option altogether ("max-allocs-per-node3000" is the default). In this program it doesn't make a huge difference.
I use 200000 for release builds and when I am looking for ways to improve the code output. A long build for a release is perfectly acceptable to me. For development you may want to go lower. I don't though, instead I properly partition a project into many source files and use a makefile so that only files I change are recompiled. This way the amount of code the compiler has to chew on is smaller and output is generated more quickly.
By the way Philip at sdcc uses 1000000 when he runs benchmarks. I can't use that number on this laptop as it will run out of memory for large programs. I also find the difference is not too much between 200000 and 1000000. Because of this we adopt 200000 as the magic number and focus efforts to improve code output for this level. I think Fuzix has adopted our 200000 number too but in earlier days it was 500000 I believe.
[свернуть]