User Tag List

Страница 8 из 19 ПерваяПервая ... 456789101112 ... ПоследняяПоследняя
Показано с 71 по 80 из 189

Тема: Языки программирования

  1. #71

    Регистрация
    14.01.2005
    Адрес
    Таганрог, Россия
    Сообщений
    4,286
    Спасибо Благодарностей отдано 
    9
    Спасибо Благодарностей получено 
    91
    Поблагодарили
    39 сообщений
    Mentioned
    8 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Снял слепки с Avoset, sdcc, z88dk. В ближайшее время попробую проанализировать и их код. У кого еще какие компилеры завалялись?

  2. #72

    Регистрация
    18.02.2005
    Адрес
    St. Petersburg
    Сообщений
    415
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    0
    Поблагодарили
    0 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от jdigreze
    Вах-вах! HI-TECH C Z80/Z180 = $950 - приятная цена!
    Что заметно дешевле KEIL. Так что как сказать...

  3. #73

    Регистрация
    18.02.2005
    Адрес
    St. Petersburg
    Сообщений
    415
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    0
    Поблагодарили
    0 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от caro
    Все попытки скачать файл с RapidShare лично для меня не увенчались успехом
    Hitech могу дать.

  4. #74

    Регистрация
    14.01.2005
    Адрес
    Таганрог, Россия
    Сообщений
    4,286
    Спасибо Благодарностей отдано 
    9
    Спасибо Благодарностей получено 
    91
    Поблагодарили
    39 сообщений
    Mentioned
    8 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Итак, препарируемый- Avocet. Этот компилятор не понял старого синтаксиса теста (см. заголовки функций), поэтому пришлось слегка его подработать напильником.
    Вот что он нагенерил (лишние директивы вырезаны).

    0.Пролог
    Код:
    ;не суть важно, все равно один раз делается...
    		push	ix
    		push	de
    		push	hl
    		ld	ix,-?TSC0
    		add	ix,sp
    		push	af
    1.Размножение констант и копий
    Код:
    		ld	hl,2
    		ld	(_j4),hl
    ;лишняя операция
    		ld	de,(_j4)
    		ld	hl,(_i2)
    		and	a
    ;использование нативных операций- плюс в копилку
    		sbc	hl,de
    ;хитровымудренная система переходов- жирный минус
    		jp	p,$+8
    		jp	pe,?BOL0
    		jr	+3
    		jp	po,?BOL0
    ?ACC0:		.equal	$
    		ld	de,(_j4)
    		ld	hl,(_i4)
    		and	a
    		sbc	hl,de
    		jp	p,$+8
    		jp	pe,?BOL0
    		jr	+3
    		jp	po,?BOL0
    ?PLC0:		.equal	$
    		ld	hl,2
    		ld	(_i2),hl
    ?BOL0:		.equal	$
    ;короче, никаких размножений констант не применяется
    ;и этот кусок- практически полная копия предыдущего
    		ld	hl,(_k5)
    		ld	(_j4),hl
    		ld	e,l
    		ld	d,h
    		ld	hl,(_i2)
    		and	a
    		sbc	hl,de
    		jp	p,$+8
    		jp	pe,?BOL1
    		jr	+3
    		jp	po,?BOL1
    ?ACC1:		.equal	$
    		ld	de,(_j4)
    		ld	hl,(_i4)
    		and	a
    		sbc	hl,de
    		jp	p,$+8
    		jp	pe,?BOL1
    		jr	+3
    		jp	po,?BOL1
    ?PLC1:		.equal	$
    		ld	hl,3
    		ld	(_i5),hl
    ?BOL1:		.equal	$
    2.Свертка констант
    Код:
    ;благополучно свернул целочисленные константы
    		ld	hl,3
    		ld	(_i3),hl
    
    		.const_data
    ?CGL0:		.double	8.69999999999999930000
    		.program
    ;также свернул дробную
    		ld	de,?CGL0
    		ld	hl,_flt_1
    		call	__store_double
    ;просто константа
    		ld	hl,5
    		ld	(_i2),hl
    ;а это убожество...
    		ld	de,0
    		ld	hl,(_i)
    		add	hl,de
    		ld	(_j2),hl
    ;здесь не сообразил что на 1 делить не надо...
    		ld	de,1
    		ld	hl,(_i)
    		call	__div_int
    		ld	(_k2),hl
    ;да и умножать тоже...
    		ld	de,1
    		ld	hl,(_i)
    		call	__mult_int
    		ld	(_i4),hl
    ;а это вообще хохма
    		ld	de,0
    		ld	hl,(_i)
    		call	__mult_int
    		ld	(_i5),hl
    ;и на 0 мы делить тоже умеем! :)
    ;как целочисленно...
    		ld	de,0
    		ld	hl,(_i)
    		call	__div_int
    		ld	(_i2),hl
    
    		.const_data
    ?CGL1:		.double	0.0
    		.program
    ;...так и с плавающей запятой
    		ld	de,?CGL1
    		ld	hl,_flt_1
    		call	__div_double
    		ex	de,hl
    		ld	hl,_flt_2
    		call	__store_double
    
    		.const_data
    ?CGL2:		.double	2.39999999999999990000
    		.program
    ;вот деление константы на константу он свернул
    		ld	de,?CGL2
    		ld	hl,_flt_3
    		call	__store_double
    
    		.const_data
    ?CGL3:		.double	1.00000010000000010000
    		.program
    ;сложение тоже
    		ld	de,?CGL3
    		ld	hl,_flt_4
    		call	__store_double
    
    		.const_data
    ?CGL4:		.double	0.0
    		.program
    ;но вот умножение на 0 не догадался облагородить
    		ld	de,?CGL4
    		ld	hl,_flt_6
    		call	__mult_double
    		ex	de,hl
    		ld	hl,_flt_5
    		call	__store_double
    ;ничего интересного
    		ld	de,_flt_3
    		ld	hl,_flt_2
    		call	__mult_double
    		ex	de,hl
    		ld	hl,_flt_6
    		call	__store_double
    3.Лишнее присваивание
    Код:
    ;за такое надо руки отрывать...
    		ld	hl,1
    		ld	(_k3),hl
    		ld	hl,1
    		ld	(_k3),hl
    4.Снижение мощности
    Код:
    ;никакой фантазии...
    		ld	de,(_j5)
    		ld	hl,4
    		call	__mult_int
    		ld	(_k2),hl
    		ld	hl,0
    		ld	(_i),hl
    ?FLC2:		.equal	$
    		ld	de,5
    		ld	hl,(_i)
    		and	a
    		sbc	hl,de
    ;опять сложная система переходов
    		jr	z,+11
    		jp	p,$+8
    		jp	pe,?BOL2
    		jr	+3
    		jp	po,?BOL2
    		jp	?FLB2
    ?FLA2:		.equal	$
    ;регистровые переменные не поддерживаются,
    ;по крайней мере здесь
    		ld	hl,(_i)
    		inc	hl
    		ld	(_i),hl
    		jp	?FLC2
    ?FLB2:		.equal	$
    ;это просто мрак...
    		ld	de,2
    		ld	hl,(_i)
    		call	__mult_int
    		ld	(ix+0),l
    		ld	(ix+0+1),h
    		ld	hl,(_i)
    		add	hl,hl
    		ld	bc,_ivector4
    		add	hl,bc
    		ld	e,l
    		ld	d,h
    ;люди, не смотрите на это :)
    		ld	l,(ix+0)
    		ld	h,(ix+0+1)
    		push	de
    		pop	iy
    		ld	(iy+0),l
    		ld	(iy+1),h
    		jp	?FLA2
    ?BOL2:		.equal	$
    5.Простой цикл
    Код:
    		ld	hl,0
    		ld	(_j5),hl
    		ld	hl,10000
    		ld	(_k5),hl
    ?TOL3:		.equal	$
    ;просто ни ума, ни фантазии...
    		ld	de,1
    		ld	hl,(_k5)
    		and	a
    		sbc	hl,de
    		ld	(_k5),hl
    		ld	de,1
    		ld	hl,(_j5)
    		add	hl,de
    		ld	(_j5),hl
    
    		ld	de,3
    		ld	hl,(_k5)
    		call	__mult_int
    		ld	(ix+0),l
    		ld	(ix+0+1),h
    		ld	de,5
    		ld	hl,(_j5)
    		call	__mult_int
    		ld	e,l
    		ld	d,h
    		ld	l,(ix+0)
    		ld	h,(ix+0+1)
    		call	__div_int
    		ld	(_i5),hl
    ?DCL3:		.equal	$
    ;просто верх кодерского разума- сравнение на 0...
    		ld	de,0
    		ld	hl,(_k5)
    		and	a
    		sbc	hl,de
    		jp	z,?BOL3
    		jp	p,$+8
    		jp	po,?BOL3
    		jr	+3
    		jp	pe,?BOL3
    ?PLC2:		.equal	$
    		jp	?TOL3
    ?BOL3:		.equal	$
    6.Управление переменной индукции цикла
    Код:
    ;достаточно приличный заголовок цикла
    		ld	hl,0
    		ld	(_i),hl
    ?FLC4:		.equal	$
    		ld	de,100
    		ld	hl,(_i)
    		and	a
    		sbc	hl,de
    		jp	p,$+8
    		jp	pe,?BOL4
    		jr	+3
    		jp	po,?BOL4
    		jp	?FLB4
    ?FLA4:		.equal	$
    		ld	hl,(_i)
    		inc	hl
    		ld	(_i),hl
    		jp	?FLC4
    ?FLB4:		.equal	$
    ;а здесь начинаются страшные вычисления без каких
    ;бы то ни было следов оптимизации
    		ld	de,2
    		ld	hl,(_i)
    		call	__mult_int
    		ld	e,l
    		ld	d,h
    		ld	hl,3
    		add	hl,de
    		add	hl,hl
    		ld	bc,_ivector5
    		add	hl,bc
    		ld	e,l
    		ld	d,h
    		ld	hl,5
    		push	de
    		pop	iy
    		ld	(iy+0),l
    		ld	(iy+1),h
    		jp	?FLA4
    ?BOL4:		.equal	$
    7. Глубокие подвыражения
    Код:
    ;без слов. все и так видно...
    		ld	de,10
    		ld	hl,(_i)
    		and	a
    		sbc	hl,de
    		jp	p,$+8
    		jp	pe,?BOL5
    		jr	+3
    		jp	po,?BOL5
    ?PLC3:		.equal	$
    		ld	de,(_i2)
    		ld	hl,(_i5)
    		add	hl,de
    		ld	(_j5),hl
    		jp	?EOI5
    ?BOL5:		.equal	$
    		ld	de,(_i2)
    		ld	hl,(_i5)
    		add	hl,de
    		ld	(_k5),hl
    ?EOI5:		.equal	$
    8.Генерация адреса переменной с константным индексом, размножение копий и регистров
    Код:
    		ld	hl,_ivector+0
    		ld	e,l
    		ld	d,h
    		ld	hl,1
    ;ребята наверное не знают про команду ld (hl),..
    		push	de
    		pop	iy
    		ld	(iy+0),l
    		ld	(iy+1),h
    		ld	hl,(_i2)
    		add	hl,hl
    		ld	bc,_ivector
    		add	hl,bc
    		ld	e,l
    		ld	d,h
    		ld	hl,2
    		push	de
    		pop	iy
    		ld	(iy+0),l
    		ld	(iy+1),h
    		ld	hl,(_i2)
    		add	hl,hl
    		ld	bc,_ivector
    		add	hl,bc
    		ld	e,l
    		ld	d,h
    		ld	hl,2
    		push	de
    		pop	iy
    		ld	(iy+0),l
    		ld	(iy+1),h
    		ld	hl,_ivector+4
    		ld	e,l
    		ld	d,h
    		ld	hl,3
    		push	de
    		pop	iy
    		ld	(iy+0),l
    		ld	(iy+1),h
    9.Удаление общих подвыражений
    Код:
    		ld	de,(_k3)
    		ld	hl,(_h3)
    		add	hl,de
    		ld	de,0
    		and	a
    		sbc	hl,de
    		jp	p,$+8
    		jp	po,?PLC4
    		jr	+3
    		jp	pe,?PLC4
    ?OCC2:		.equal	$
    		ld	de,(_k3)
    		ld	hl,(_h3)
    		add	hl,de
    		ld	de,5
    		and	a
    		sbc	hl,de
    		jp	z,?BOL6
    		jp	p,$+8
    		jp	po,?BOL6
    		jr	+3
    		jp	pe,?BOL6
    ?PLC4:		.equal	$
    		.const_data
    ?PLC5:		.byte	"Common subexpression elimination",0ah,0
    		.program
    		ld	hl,?PLC5
    		call	_printf
    		jp	?EOI6
    ?BOL6:		.equal	$
    ;иными словами, никаких выделений не производится
    		ld	de,(_k3)
    		ld	hl,(_h3)
    		add	hl,de
    		ld	de,(_i3)
    		call	__div_int
    		ld	(_m3),hl
    		ld	de,(_k3)
    		ld	hl,(_h3)
    		add	hl,de
    		ld	e,l
    		ld	d,h
    		ld	hl,(_i3)
    		add	hl,de
    		ld	(_g3),hl
    ?EOI6:		.equal	$
    10.Вынесение инвариантного кода
    Код:
    ;приемлимое начало цикла
    		ld	hl,0
    		ld	(_i4),hl
    ?FLC7:		.equal	$
    		ld	de,2
    		ld	hl,(_i4)
    		and	a
    		sbc	hl,de
    		jr	z,+11
    ;но его структура в коде просто ужасна!
    		jp	p,$+8
    		jp	pe,?BOL7
    		jr	+3
    		jp	po,?BOL7
    		jp	?FLB7
    ?FLA7:		.equal	$
    		ld	hl,(_i4)
    		inc	hl
    		ld	(_i4),hl
    		jp	?FLC7
    ?FLB7:		.equal	$
    ;никакого вынесения нет- вычисления на каждой итерации
    		ld	de,(_k)
    		ld	hl,(_j)
    		call	__mult_int
    		ld	(ix+0),l
    		ld	(ix+0+1),h
    		ld	hl,(_i4)
    		ld	bc,_ivector2
    		add	hl,bc
    		ld	e,l
    		ld	d,h
    		ld	l,(ix+0)
    		ld	h,(ix+0+1)
    		ld	a,l
    		ld	(de),a
    		jp	?FLA7

  5. #75

    Регистрация
    14.01.2005
    Адрес
    Таганрог, Россия
    Сообщений
    4,286
    Спасибо Благодарностей отдано 
    9
    Спасибо Благодарностей получено 
    91
    Поблагодарили
    39 сообщений
    Mentioned
    8 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    11.Вызов функции с аргументами. Определение недостижимого кода
    Код:
    		.const_data
    ?PLC6:		.byte	"This line should not be printed",0
    		.program
    ;хоть тут никаких изысков, параметры в регистрах
    		ld	de,?PLC6
    		ld	hl,1
    		call	_dead_code
    Код:
    _dead_code:	.equal	$
    ;страшный пролог!
    		push	ix
    		push	de
    		push	hl
    		ld	ix,-?TSC1
    		add	ix,sp
    		push	af
    
    		ld	l,(ix+0+?TSC1)
    		ld	h,(ix+0+?TSC1+1)
    		ld	(ix-2),l
    		ld	(ix-2+1),h
    ;страх и ужас!
    		ld	a,0
    		cp	a,0
    		jp	z,?BOL8
    ?PLC7:		.equal	$
    		.const_data
    ?PLC8:		.byte	"%s",0ah,0
    		.program
    		ld	e,(ix+2+?TSC1)
    		ld	d,(ix+2+?TSC1+1)
    		ld	hl,?PLC8
    		call	_printf
    ?BOL8:		.equal	$
    ?BOF1:		.equal	$
    ;и не менее страшный эпилог
    		pop	bc
    		pop	bc
    		pop	bc
    		pop	ix
    		ret
    12.Вызов функции без аргументов. Исключение циклов
    Код:
    ;как обычно, ничего никуда не передаем
    		call	_unnecessary_loop
    Код:
    _unnecessary_loop:	.equal	$
    		push	ix
    		ld	ix,-?TSC2
    		add	ix,sp
    		push	af
    ;все тот же кошмарный пролог...
    		ld	hl,0
    		ld	(ix-2),l
    		ld	(ix-2+1),h
    		ld	hl,0
    		ld	(_i),hl
    ?FLC9:		.equal	$
    		ld	de,5
    		ld	hl,(_i)
    		and	a
    		sbc	hl,de
    		jp	p,$+8
    		jp	pe,?BOL9
    		jr	+3
    		jp	po,?BOL9
    		jp	?FLB9
    ?FLA9:		.equal	$
    		ld	hl,(_i)
    		inc	hl
    		ld	(_i),hl
    		jp	?FLC9
    ?FLB9:		.equal	$
    ;постоянные вычисления, тут даже пресловутое
    ;примечание опускает руки :)
    		ld	de,(_j5)
    		ld	l,(ix-2)
    		ld	h,(ix-2+1)
    		add	hl,de
    		ld	(_k5),hl
    		jp	?FLA9
    ?BOL9:		.equal	$
    ?BOF2:		.equal	$
    		pop	bc
    		pop	ix
    		ret
    13. Слияние заголовков циклов
    Код:
    _loop_jamming:	.equal	$
    		push	ix
    		push	hl
    		ld	ix,-?TSC3
    		add	ix,sp
    		ld	hl,0
    		ld	(_i),hl
    ?FLC10:		.equal	$
    		ld	de,5
    		ld	hl,(_i)
    		and	a
    		sbc	hl,de
    		jp	p,$+8
    		jp	pe,?BOL10
    		jr	+3
    		jp	po,?BOL10
    		jp	?FLB10
    ?FLA10:		.equal	$
    		ld	hl,(_i)
    		inc	hl
    		ld	(_i),hl
    		jp	?FLC10
    ?FLB10:		.equal	$
    		ld	de,(_i)
    		ld	hl,(_j5)
    		call	__mult_int
    		ld	e,l
    		ld	d,h
    		ld	l,(ix+0+?TSC3)
    		ld	h,(ix+0+?TSC3+1)
    		add	hl,de
    		ld	(_k5),hl
    		jp	?FLA10
    ?BOL10:		.equal	$
    ;никакого слияния плюс страшные вычисления
    		ld	hl,0
    		ld	(_i),hl
    ?FLC11:		.equal	$
    		ld	de,5
    		ld	hl,(_i)
    		and	a
    		sbc	hl,de
    		jp	p,$+8
    		jp	pe,?BOL11
    		jr	+3
    		jp	po,?BOL11
    		jp	?FLB11
    ?FLA11:		.equal	$
    		ld	hl,(_i)
    		inc	hl
    		ld	(_i),hl
    		jp	?FLC11
    ?FLB11:		.equal	$
    		ld	de,(_k5)
    		ld	l,(ix+0+?TSC3)
    		ld	h,(ix+0+?TSC3+1)
    		call	__mult_int
    		ld	e,l
    		ld	d,h
    		ld	hl,(_i)
    		call	__mult_int
    		ld	(_i5),hl
    		jp	?FLA11
    ?BOL11:		.equal	$
    ?BOF3:		.equal	$
    		pop	bc
    		pop	ix
    		ret
    14.Разворачивание циклов
    Код:
    _loop_unrolling:	.equal	$
    		push	ix
    		push	hl
    		ld	ix,-?TSC4
    		add	ix,sp
    		ld	hl,0
    		ld	(_i),hl
    ?FLC12:		.equal	$
    ;разворота нет
    		ld	de,6
    		ld	hl,(_i)
    		and	a
    		sbc	hl,de
    		jp	p,$+8
    		jp	pe,?BOL12
    		jr	+3
    		jp	po,?BOL12
    		jp	?FLB12
    ?FLA12:		.equal	$
    		ld	hl,(_i)
    		inc	hl
    		ld	(_i),hl
    		jp	?FLC12
    ?FLB12:		.equal	$
    ;да еще и вычисления страшные
    		ld	hl,(_i)
    ;хоть не догадался умножать на 2 процедурой...
    		add	hl,hl
    		ld	bc,_ivector4
    		add	hl,bc
    		ld	e,l
    		ld	d,h
    		ld	hl,0
    		push	de
    		pop	iy
    		ld	(iy+0),l
    		ld	(iy+1),h
    		jp	?FLA12
    ?BOL12:		.equal	$
    ?BOF4:		.equal	$
    		pop	bc
    		pop	ix
    		ret
    15.Сжатие цепочки переходов
    Код:
    _jump_compression:	.equal	$
    		push	ix
    		push	de
    		push	hl
    		ld	ix,-?TSC5
    		add	ix,sp
    		.c_start  0ba1h,260
    ?beg_1:		.equal	$
    		ld	e,(ix+2+?TSC5)
    		ld	d,(ix+2+?TSC5+1)
    		ld	l,(ix+0+?TSC5)
    		ld	h,(ix+0+?TSC5+1)
    		and	a
    		sbc	hl,de
    		jp	p,$+8
    		jp	pe,?BOL13
    		jr	+3
    		jp	po,?BOL13
    ?PLC9:		.equal	$
    		ld	e,(ix+8+?TSC5)
    		ld	d,(ix+8+?TSC5+1)
    		ld	l,(ix+2+?TSC5)
    		ld	h,(ix+2+?TSC5+1)
    		and	a
    		sbc	hl,de
    		jp	p,$+8
    		jp	pe,?BOL14
    		jr	+3
    		jp	po,?BOL14
    ?PLC10:		.equal	$
    		ld	e,(ix+10+?TSC5)
    		ld	d,(ix+10+?TSC5+1)
    		ld	l,(ix+8+?TSC5)
    		ld	h,(ix+8+?TSC5+1)
    		and	a
    		sbc	hl,de
    		jp	p,$+8
    		jp	pe,?BOL15
    		jr	+3
    		jp	po,?BOL15
    ?PLC11:		.equal	$
    		ld	e,(ix+12+?TSC5)
    		ld	d,(ix+12+?TSC5+1)
    		ld	l,(ix+10+?TSC5)
    		ld	h,(ix+10+?TSC5+1)
    		and	a
    		sbc	hl,de
    		jp	p,$+8
    		jp	pe,?BOL16
    		jr	+3
    		jp	po,?BOL16
    ?PLC12:		.equal	$
    		ld	e,(ix+12+?TSC5)
    		ld	d,(ix+12+?TSC5+1)
    		ld	l,(ix+10+?TSC5)
    		ld	h,(ix+10+?TSC5+1)
    		add	hl,de
    		ld	(ix+10+?TSC5),l
    		ld	(ix+10+?TSC5+1),h
    		jp	?EOI16
    ?BOL16:		.equal	$
    ;нет оптимизации
    		jp	?end_1
    ?EOI16:		.equal	$
    		jp	?EOI15
    ?BOL15:		.equal	$
    		ld	e,(ix+10+?TSC5)
    		ld	d,(ix+10+?TSC5+1)
    		ld	l,(ix+8+?TSC5)
    		ld	h,(ix+8+?TSC5+1)
    		add	hl,de
    		ld	(ix+8+?TSC5),l
    		ld	(ix+8+?TSC5+1),h
    ?EOI15:		.equal	$
    		jp	?EOI14
    ?BOL14:		.equal	$
    		ld	e,(ix+8+?TSC5)
    		ld	d,(ix+8+?TSC5+1)
    		ld	l,(ix+2+?TSC5)
    		ld	h,(ix+2+?TSC5+1)
    		add	hl,de
    		ld	(ix+2+?TSC5),l
    		ld	(ix+2+?TSC5+1),h
    ?end_1:		.equal	$
    		jp	?beg_1
    ?EOI14:		.equal	$
    		jp	?EOI13
    ?BOL13:		.equal	$
    		ld	e,(ix+2+?T
    ;а дальше текст почемуто потерян...
    Итоговая оценка- 4/10. Поставил бы 3/10, да понравился достаточно легкий заголовок цикла.
    Плюс данный компилятор распространяетя со средой разработки и отладки под винду. Опций настройки я не нашел- они задавались в настройках проекта, но в хелпе я нашел не все указанные опции. Про оптимизацию там не было сказано ни слова. Итого- это просто транслятор с примитивной сверткой констант (и только!). Выходной ассемблерный файл без указания строк исходного файла, весьма неудобно по нему лазить.
    Короче, использовать не рекомендуется

  6. #76

    Регистрация
    14.01.2005
    Адрес
    Таганрог, Россия
    Сообщений
    4,286
    Спасибо Благодарностей отдано 
    9
    Спасибо Благодарностей получено 
    91
    Поблагодарили
    39 сообщений
    Mentioned
    8 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Следующий кандидат- Small Device C Compiler
    Испытания проводились с оптимизацией по размеру и по скорости- результат одинаковый.

    0. Пролог.
    Код:
    ;классика жанра для переменных в стеке
    _main:
    	push	ix
    	ld	ix,#0
    	add	ix,sp
    1. Тест на размножение констант и копий.
    Код:
    ;жирный-жирный минус- использование тяжелой
    ;артиллерии в виде индексных регистров
    ;test.c:59: j4 = 2;
    	ld	iy,#_j4
    	ld	0(iy),#0x02
    	ld	1(iy),#0x00
    ;test.c:60: if( i2 < j4 && i4 < j4 )
    ;вот оно- распространение констант в действии!!!
    	ld	iy,#_i2
    ;вместо вычитания j4 используется  вычитание константы
    	ld	a,0(iy)
    	sub	a,#0x02
    	ld	a,1(iy)
    	sbc	a,#0x00
    	jp	p,00102$
    ;аналогично вторая половина
    	ld	iy,#_i4
    	ld	a,0(iy)
    	sub	a,#0x02
    	ld	a,1(iy)
    	sbc	a,#0x00
    	jp	p,00102$
    ;test.c:61: i2 = 2;
    ;опять IY...
    	ld	iy,#_i2
    	ld	0(iy),#0x02
    	ld	1(iy),#0x00
    00102$:
    ;test.c:63: j4 = k5;
    ;ну почему загрузка сделана нормально, но сохранение
    ;так лажово?
    	ld	hl,(_k5)
    	ld	iy,#_j4
    	ld	0(iy),l
    	ld	1(iy),h
    ;test.c:64: if( i2 < j4 && i4 < j4 )
    ;просто страшная перезагрузка!!! нет использования
    ;предыдущего операнда в hl!!!
    	ld	iy,#_i2
    	ld	a,0(iy)
    	ld	iy,#_j4
    	sub	a,0(iy)
    	ld	iy,#_i2
    	ld	a,1(iy)
    	ld	iy,#_j4
    	sbc	a,1(iy)
    	jp	p,00105$
    ;то же самое...
    	ld	iy,#_i4
    	ld	a,0(iy)
    	ld	iy,#_j4
    	sub	a,0(iy)
    	ld	iy,#_i4
    	ld	a,1(iy)
    	ld	iy,#_j4
    	sbc	a,1(iy)
    	jp	p,00105$
    ;test.c:65: i5 = 3;
    	ld	iy,#_i5
    	ld	0(iy),#0x03
    	ld	1(iy),#0x00
    00105$:
    2.Свертка констант
    Код:
    ;test.c:72: i3 = 1 + 2;
    ;свернул
    	ld	iy,#_i3
    	ld	0(iy),#0x03
    	ld	1(iy),#0x00
    ;test.c:73: flt_1 = 2.4 + 6.3;
    ;вот здесь использование индексных регистров можно
    ;оправдать, да и то с натяжкой...
    	ld	iy,#_flt_1
    	ld	0(iy),#0x33
    	ld	1(iy),#0x33
    	ld	2(iy),#0x0B
    	ld	3(iy),#0x41
    ;test.c:74: i2 = 5;
    	ld	iy,#_i2
    	ld	0(iy),#0x05
    	ld	1(iy),#0x00
    ;test.c:75: j2 = i + 0;
    ;0 не стал добавлять, просто копирование
    	ld	hl,(_i)
    	ld	iy,#_j2
    	ld	0(iy),l
    	ld	1(iy),h
    ;test.c:76: k2 = i / 1;
    ;и на 1 делить не стал
    	ld	hl,(_i)
    	ld	iy,#_k2
    	ld	0(iy),l
    	ld	1(iy),h
    ;test.c:77: i4 = i * 1;
    ;да и умножать тоже
    	ld	hl,(_i)
    	ld	iy,#_i4
    	ld	0(iy),l
    	ld	1(iy),h
    ;test.c:78: i5 = i * 0;
    ;сообразительный малый :)
    	ld	iy,#_i5
    	ld	0(iy),#0x00
    	ld	1(iy),#0x00
    ;test.c:88: printf( "This compiler handles divide-by-zero as 
    ;деление на 0 не словил на этапе комппиляции, пытается
    ;печатать
    ;передача параметров через стек- не очень хорошо...
    	ld	hl,#__str_0
    	push	hl
    	call	_printf
    ;и очистка вызывающей функцией- классическая
    ;парадигма _cdecl
    	pop	af
    ;test.c:91: flt_3 = 2.4 / 1.0;
    ;с плавающей запятой константы тоже сворачивает
    	ld	iy,#_flt_3
    	ld	0(iy),#0x9A
    	ld	1(iy),#0x99
    	ld	2(iy),#0x19
    	ld	3(iy),#0x40
    ;test.c:92: flt_4 = 1.0 + 0.0000001;
    	ld	iy,#_flt_4
    	ld	0(iy),#0x01
    	ld	1(iy),#0x00
    	ld	2(iy),#0x80
    	ld	3(iy),#0x3F
    ;test.c:93: flt_5 = flt_6 * 0.0;
    ;молодец :)
    	ld	iy,#_flt_5
    	ld	0(iy),#0x00
    	ld	1(iy),#0x00
    	ld	2(iy),#0x00
    	ld	3(iy),#0x00
    ;test.c:94: flt_6 = flt_2 * flt_3;
    ;распространение константы flt_3 = 2.4
    	ld	hl,#0x4019
    	push	hl
    	ld	hl,#0x999A
    	push	hl
    	ld	hl,(_flt_2 + 2)
    	push	hl
    	ld	hl,(_flt_2)
    	push	hl
    	call	___fsmul
    ;заволновался по поводу hl...
    	ld	b,h
    	ld	c,l
    ;освобождение стека- 8 байт
    	pop	af
    	pop	af
    	pop	af
    	pop	af
    	ld	iy,#_flt_6
    	ld	0(iy),c
    	ld	1(iy),b
    	ld	2(iy),e
    	ld	3(iy),d
    3.Лишнее присваивание
    Код:
    ;test.c:101: k3 = 1;
    ;было благополучно удалено!
    	ld	iy,#_k3
    	ld	0(iy),#0x01
    	ld	1(iy),#0x00
    4.Снижение мощности
    Код:
    ;test.c:107: k2 = 4 * j5;
    ;это просто "шедевр"! это надо видеть!!!
    	ld	iy,#_j5
    	ld	a,0(iy)
    	ld	iy,#_k2
    	ld	0(iy),a
    	ld	iy,#_j5
    	ld	a,1(iy)
    	ld	iy,#_k2
    	ld	1(iy),a
    ;впервые на манеже ТАКИЕ извращения при попытке
    ;заменить умножение сдвигами :)
    	ld	a,#0x02+1
    	jp	00146$
    00145$:
    	ld	iy,#_k2
    	sla	0(iy)
    	rl	1(iy)
    00146$:
    	dec	a
    	jp	nz,00145$
    
    ;test.c:108: for( i = 0; i <= 5; i++ )
    ;переменная цикла тоже в индексном... грустно...
    	ld	iy,#_i
    	ld	0(iy),#0x00
    	ld	1(iy),#0x00
    00117$:
    	ld	a,#0x05
    	ld	iy,#_i
    	sub	a,0(iy)
    	ld	a,#0x00
    	sbc	a,1(iy)
    	jp	m,00120$
    ;test.c:109: ivector4[ i ] = i * 2;
    ;мрачно...
    	ld	c,0(iy)
    	ld	b,1(iy)
    	sla	c
    	rl	b
    
    	ld	hl,#_ivector4
    	add	hl,bc
    ;так и не понял, для чего эти две команды...
    	ld	e,l
    	ld	d,h
    	ld	(hl),c
    	inc	hl
    	ld	(hl),b
    ;test.c:108: for( i = 0; i <= 5; i++ )
    ;а вот это небольшой финт- полупересчетка
    	ld	iy,#_i
    	inc	0(iy)
    	jp	nz,00149$
    	inc	1(iy)
    00149$:
    	jp	00117$
    00120$:
    5.Простой цикл
    Код:
    ;test.c:115: j5 = 0;
    	ld	iy,#_j5
    	ld	0(iy),#0x00
    	ld	1(iy),#0x00
    ;test.c:116: k5 = 10000;
    	ld	iy,#_k5
    	ld	0(iy),#0x10
    	ld	1(iy),#0x27
    ;test.c:117: do {
    00107$:
    ;test.c:118: k5 = k5 - 1;
    ;ну достаточно логичная конструкция- почему в остальных
    ;местах IY????
    	ld	hl,(_k5)
    	dec	hl
    	ld	(_k5),hl
    ;test.c:119: j5 = j5 + 1;
    ;например, здесь????
    	ld	iy,#_j5
    	inc	0(iy)
    	jp	nz,00150$
    	inc	1(iy)
    00150$:
    ;test.c:120: i5 = (k5 * 3) / (j5 * constant5);
    ;ну просто конфетка! :)
    	ld	de,(_k5)
    	ld	l,e
    	ld	h,d
    	add	hl,hl
    	add	hl,de
    	ld	c,l
    	ld	b,h
    ;он даже константу развернул!!!
    	ld	de,(_j5)
    	ld	l,e
    	ld	h,d
    	add	hl,hl
    	add	hl,hl
    	add	hl,de
    	ld	e,l
    	ld	d,h
    ;параметры через стек
    	push	de
    	push	bc
    	call	__divsint_rrx_s
    ;непонятного назначения конструкция...
    	ld	b,h
    	ld	c,l
    	pop	af
    	pop	af
    	ld	iy,#_i5
    	ld	0(iy),c
    	ld	1(iy),b
    ;test.c:121: } while ( k5 > 0 );
    ;страшная конструкция...
    	ld	a,#0x00
    	ld	iy,#_k5
    	sub	a,0(iy)
    	ld	a,#0x00
    	sbc	a,1(iy)
    	jp	m,00107$
    6.Управление переменной индукции цикла
    Код:
    ;test.c:126: for( i = 0; i < 100; i++ )
    ;стандартный заголовок цикла
    	ld	iy,#_i
    	ld	0(iy),#0x00
    	ld	1(iy),#0x00
    00121$:
    	ld	iy,#_i
    	ld	a,0(iy)
    	sub	a,#0x64
    	ld	a,1(iy)
    	sbc	a,#0x00
    	jp	p,00124$
    ;test.c:127: ivector5[ i * 2 + 3 ] = 5;
    ;выделение индукции нет, но интересно- сообразил, что 
    ; переменная цикла помещается в один байт
    	ld	c,0(iy)
    	ld	a,c
    	add	a,a
    	ld	c,a
    ;эх, не догадался базу массива сместить :)
    	inc	c
    	inc	c
    	inc	c
    ;не забываем про размер
    	ld	a,c
    	add	a,a
    	ld	c,a
    ;вот это интересно- использование полуслов адреса
    	ld	a,#<_ivector5
    	add	a,c
    	ld	c,a
    	ld	a,#>_ivector5
    	adc	a,#0x00
    	ld	b,a
    ;бережет он HL непонятно с какими целями...
    	ld	l,c
    	ld	h,b
    	ld	(hl),#0x05
    	inc	hl
    	ld	(hl),#0x00
    ;test.c:126: for( i = 0; i < 100; i++ )
    ;стандарный инкремент
    	inc	0(iy)
    	jp	nz,00151$
    	inc	1(iy)
    00151$:
    	jp	00121$
    00124$:
    7.Глубокие подвыражения
    Код:
    ;test.c:133: if( i < 10 )
    	ld	iy,#_i
    	ld	a,0(iy)
    	sub	a,#0x0A
    	ld	a,1(iy)
    	sbc	a,#0x00
    	jp	p,00111$
    ;test.c:134: j5 = i5 + i2;
    ;страхолюдная конструкция...
    	ld	hl,#_i2
    	push	de
    	ld	iy,#_j5
    	push	iy
    	pop	de
    	ld	iy,#_i5
    	ld	a,0(iy)
    	add	a,(hl)
    	ld	(de),a
    	ld	a,1(iy)
    	inc	hl
    	adc	a,(hl)
    	inc	de
    	ld	(de),a
    	pop	de
    	jp	00112$
    00111$:
    ;test.c:136: k5 = i5 + i2;
    ;иными словами- никакого выделения общего подвыражения нет
    	ld	hl,#_i2
    	push	de
    	ld	iy,#_k5
    	push	iy
    	pop	de
    	ld	iy,#_i5
    	ld	a,0(iy)
    	add	a,(hl)
    	ld	(de),a
    	ld	a,1(iy)
    	inc	hl
    	adc	a,(hl)
    	inc	de
    	ld	(de),a
    	pop	de
    00112$:
    8.Генерация адреса переменной с константным индексом, размножение копий и регистров
    Код:
    ;test.c:144: ivector[ 0 ] = 1;
    ;ну почему в обычном варианте этого нет???
    	ld	hl,#_ivector
    	ld	(hl),#0x01
    	inc	hl
    	ld	(hl),#0x00
    ;test.c:145: ivector[ i2 ] = 2;
    ;страсти-то какие...
    	ld	iy,#_i2
    	ld	c,0(iy)
    	ld	b,1(iy)
    	sla	c
    	rl	b
    	dec	hl
    	add	hl,bc
    	ld	c,l
    	ld	b,h
    	ld	(hl),#0x02
    	inc	hl
    	ld	(hl),#0x00
    ;test.c:146: ivector[ i2 ] = 2;
    ;эти две команды лишние, но в целом используется
    ;результат предыдущих вычислений
    	ld	l,c
    	ld	h,b
    	ld	(hl),#0x02
    	inc	hl
    	ld	(hl),#0x00
    ;test.c:147: ivector[ 2 ] = 3;
    ;почему так странно?
    	ld	bc,#_ivector + 4
    	ld	l,c
    	ld	h,b
    	ld	(hl),#0x03
    	inc	hl
    	ld	(hl),#0x00
    9.Удаление общих подвыражений
    Код:
    ;test.c:154: if(( h3 + k3 ) < 0 || ( h3 + k3 ) > 5 )
    ;советую присмотреться внимательно- компилятор
    ;запомнил, что k3 не менялся и равен 1- размножение
    ;константы плюс сокращенные вычисления плюс сразу
    ;два сравнения
    ;ЗЫ. закрывайте глаза на реализацию идеи :)
    	ld	iy,#_h3
    	ld	c,0(iy)
    	ld	b,1(iy)
    ;вот это мы добавляем к3
    	inc	bc
    ;проверка на <0 - проще простого
    	ld	a,b
    	bit	7,a
    	jp	nz,00113$
    ;а также на >5
    	ld	a,#0x05
    	sub	a,c
    	ld	a,#0x00
    	sbc	a,b
    	jp	p,00114$
    00113$:
    ;test.c:155: printf("Common subexpression elimination\n");
    ;параметры через стек
    	ld	hl,#__str_1
    	push	hl
    	call	_printf
    	pop	af
    	jp	00115$
    00114$:
    ;test.c:157: m3 = ( h3 + k3 ) / i3;
    ;выделение общих подвыражений действует!- выражение
    ;в скобках не вычисляется повторно, а хранится в bc
    	push	bc
    	ld	hl,(_i3)
    	push	hl
    	push	bc
    	call	__divsint_rrx_s
    	ld	d,h
    	ld	e,l
    	pop	af
    	pop	af
    	pop	bc
    	ld	iy,#_m3
    	ld	0(iy),e
    	ld	1(iy),d
    ;test.c:158: g3 = i3 + (h3 + k3);
    ;аналогично и здесь
    	ld	hl,#_g3
    	ld	iy,#_i3
    	ld	a,0(iy)
    	add	a,c
    	ld	(hl),a
    	ld	a,1(iy)
    	adc	a,b
    	inc	hl
    	ld	(hl),a
    00115$:
    10.Вынесение инвариантного кода
    Код:
    ;test.c:166: for( i4 = 0; i4 <= max_vector; i4++)
    	ld	iy,#_i4
    	ld	0(iy),#0x00
    	ld	1(iy),#0x00
    00125$:
    	ld	a,#0x02
    	ld	iy,#_i4
    	sub	a,0(iy)
    	ld	a,#0x00
    	sbc	a,1(iy)
    	jp	m,00128$
    ;test.c:167: ivector2[ i4 ] = j * k;
    ;весьма оригинальное разыменование указателя
    	ld	hl,#_i4
    	ld	a,#<_ivector2
    	add	a,(hl)
    	ld	c,a
    	ld	a,#>_ivector2
    	inc	hl
    	adc	a,(hl)
    	ld	b,a
    ;но вынесения инвариантной части нет- каждый цикл
    ;выполняются вычисления
    	ld	iy,#_j
    	ld	e,0(iy)
    	ld	iy,#_k
    	ld	d,0(iy)
    	push	bc
    	push	de
    	inc	sp
    	ld	a,e
    	push	af
    	inc	sp
    	call	__mulschar_rrx_s
    	ld	e,l
    	pop	af
    	pop	bc
    	ld	a,e
    	ld	(bc),a
    ;test.c:166: for( i4 = 0; i4 <= max_vector; i4++)
    	ld	iy,#_i4
    	inc	0(iy)
    	jp	nz,00154$
    	inc	1(iy)
    00154$:
    	jp	00125$
    00128$:

  7. #76
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

  8. #77

    Регистрация
    14.01.2005
    Адрес
    Таганрог, Россия
    Сообщений
    4,286
    Спасибо Благодарностей отдано 
    9
    Спасибо Благодарностей получено 
    91
    Поблагодарили
    39 сообщений
    Mentioned
    8 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    11.Вызов функции с аргументами. Определение недостижимого кода
    Код:
    ;test.c:173: dead_code( 1, "This line should not be printed" );
    ;обычная передача параметров через стек и очистка
    	ld	hl,#__str_2
    	push	hl
    	ld	hl,#0x0001
    	push	hl
    	call	_dead_code
    	pop	af
    	pop	af
    Код:
    _dead_code:
    ;лишнее выделение стекового места, но полная оптимизация
    ;внутренностей функции
    	push	ix
    	ld	ix,#0
    	add	ix,sp
    ;test.c:196: printf( "%s\n", b );
    00103$:
    	pop	ix
    	ret
    12.Вызов функции без аргументов. Исключение циклов
    Код:
    ;test.c:179: unnecessary_loop();
    	call	_unnecessary_loop
    00129$:
    Код:
    _unnecessary_loop:
    ;test.c:212: for( i = 0; i < 5; i++ )
    	ld	iy,#_i
    ;обратите внимание- компилятор перевернул цикл!
    	ld	0(iy),#0x05
    	ld	1(iy),#0x00
    00103$:
    ;test.c:214: k5 = x + j5;
    ;размножение константы х = 0
    ;но повторная загрузка имеется, простительно
    	ld	hl,(_j5)
    	ld	iy,#_k5
    	ld	0(iy),l
    	ld	1(iy),h
    	ld	hl,(_i)
    	dec	hl
    	ld	(_i),hl
    ;test.c:212: for( i = 0; i < 5; i++ )
    ;оригинальная концовка!
    	ld	iy,#_i
    	ld	a,0(iy)
    	or	a,1(iy)
    	jp	nz,00103$
    ;а этот код потому что i является глобально переменной
    	ld	0(iy),#0x05
    	ld	1(iy),#0x00
    00104$:
    	ret
    13. Слияние заголовков циклов
    Код:
    _loop_jamming:
    	push	ix
    	ld	ix,#0
    	add	ix,sp
    ;test.c:226: for( i = 0; i < 5; i++ )
    	ld	iy,#_i
    	ld	0(iy),#0x00
    	ld	1(iy),#0x00
    00101$:
    	ld	iy,#_i
    	ld	a,0(iy)
    	sub	a,#0x05
    	ld	a,1(iy)
    	sbc	a,#0x00
    	jp	p,00104$
    ;test.c:227: k5 = x + j5 * i;
    	ld	hl,(_i)
    	push	hl
    	ld	hl,(_j5)
    	push	hl
    	call	__mulint_rrx_s
    	ld	b,h
    	ld	c,l
    	pop	af
    	pop	af
    ;переменная x хранится в стеке
    	ld	hl,#_k5
    	ld	a,4(ix)
    	add	a,c
    	ld	(hl),a
    	ld	a,5(ix)
    	adc	a,b
    	inc	hl
    	ld	(hl),a
    ;test.c:226: for( i = 0; i < 5; i++ )
    	ld	iy,#_i
    	inc	0(iy)
    	jp	nz,00115$
    	inc	1(iy)
    00115$:
    	jp	00101$
    00104$:
    ;test.c:228: for( i = 0; i < 5; i++ )
    ;слияния заголовков нет
    	ld	iy,#_i
    	ld	0(iy),#0x00
    	ld	1(iy),#0x00
    00105$:
    	ld	iy,#_i
    	ld	a,0(iy)
    	sub	a,#0x05
    	ld	a,1(iy)
    	sbc	a,#0x00
    	jp	p,00109$
    ;test.c:229: i5 = x * k5 * i;
    	ld	hl,(_k5)
    	push	hl
    	ld	l,4(ix)
    	ld	h,5(ix)
    	push	hl
    	call	__mulint_rrx_s
    	ld	b,h
    	ld	c,l
    	pop	af
    	pop	af
    	ld	hl,(_i)
    	push	hl
    	push	bc
    	call	__mulint_rrx_s
    	ld	b,h
    	ld	c,l
    	pop	af
    	pop	af
    	ld	iy,#_i5
    	ld	0(iy),c
    	ld	1(iy),b
    ;test.c:228: for( i = 0; i < 5; i++ )
    	ld	iy,#_i
    	inc	0(iy)
    	jp	nz,00116$
    	inc	1(iy)
    00116$:
    	jp	00105$
    00109$:
    	pop	ix
    	ret
    14.Разворачивание циклов
    Код:
    _loop_unrolling:
    	push	ix
    	ld	ix,#0
    	add	ix,sp
    ;test.c:243: for( i = 0; i < 6; i++ )
    ;разворота нет
    	ld	iy,#_i
    	ld	0(iy),#0x00
    	ld	1(iy),#0x00
    00101$:
    	ld	iy,#_i
    	ld	a,0(iy)
    	sub	a,#0x06
    	ld	a,1(iy)
    	sbc	a,#0x00
    	jp	p,00105$
    ;test.c:244: ivector4[ i ] = 0;
    ;экзотическая загрузка :)
    	ld	c,0(iy)
    	ld	b,1(iy)
    	sla	c
    	rl	b
    	ld	hl,#_ivector4
    	add	hl,bc
    	ld	c,l
    	ld	b,h
    	ld	(hl),#0x00
    	inc	hl
    	ld	(hl),#0x00
    ;test.c:243: for( i = 0; i < 6; i++ )
    	ld	iy,#_i
    	inc	0(iy)
    	jp	nz,00111$
    	inc	1(iy)
    00111$:
    	jp	00101$
    00105$:
    	pop	ix
    	ret
    15.Сжатие цепочки переходов
    Код:
    _jump_compression:
    	push	ix
    	ld	ix,#0
    	add	ix,sp
    ;test.c:256: beg_1:
    	ld	a,8(ix)
    	sub	a,10(ix)
    	ld	a,9(ix)
    	sbc	a,11(ix)
    ;интересный финт- в С результат сравнения k и l
    	rlca
    	and	a,#0x01
    	ld	c,a
    	ld	a,10(ix)
    	sub	a,12(ix)
    	ld	a,11(ix)
    	sbc	a,13(ix)
    ;а в А результат сравнения l и m
    	rlca
    	and	a,#0x01
    ;только он почему-то не используется, а теряется...
    00101$:
    ;test.c:257: if( i < j )
    	ld	a,4(ix)
    	sub	a,6(ix)
    	ld	a,5(ix)
    	sbc	a,7(ix)
    	jp	p,00113$
    ;test.c:259: if( j < k )
    	ld	a,6(ix)
    	sub	a,8(ix)
    	ld	a,7(ix)
    	sbc	a,9(ix)
    	jp	p,00110$
    ;test.c:261: if( k < l )
    ;использование предыдущего результата
    	xor	a,a
    	or	a,c
    	jp	z,00106$
    ;test.c:263: if( l < m )
    ;очень странный код... не понимаю как работает....
    	or	a,a
    ;есть свертка перехода!
    	jp	z,00101$
    ;test.c:264: l += m;
    	ld	a,10(ix)
    	add	a,12(ix)
    	ld	10(ix),a
    	ld	a,11(ix)
    	adc	a,13(ix)
    	ld	11(ix),a
    	jp	00114$
    ;test.c:266: goto end_1;
    ;	genLabel
    00106$:
    ;test.c:269: k += l;
    	ld	a,8(ix)
    	add	a,10(ix)
    	ld	8(ix),a
    	ld	a,9(ix)
    	adc	a,11(ix)
    	ld	9(ix),a
    	jp	00114$
    00110$:
    ;test.c:273: j += k;
    	ld	a,6(ix)
    	add	a,8(ix)
    	ld	6(ix),a
    	ld	a,7(ix)
    	adc	a,9(ix)
    	ld	7(ix),a
    ;test.c:275: goto beg_1;
    	jp	00101$
    00113$:
    ;test.c:279: i += j;
    	ld	a,4(ix)
    	add	a,6(ix)
    	ld	4(ix),a
    	ld	a,5(ix)
    	adc	a,7(ix)
    	ld	5(ix),a
    00114$:
    ;test.c:280: return( i + j + k + l + m );
    	ld	a,4(ix)
    	add	a,6(ix)
    	ld	c,a
    	ld	a,5(ix)
    	adc	a,7(ix)
    	ld	b,a
    	ld	a,c
    	add	a,8(ix)
    	ld	c,a
    	ld	a,b
    	adc	a,9(ix)
    	ld	b,a
    	ld	a,c
    	add	a,10(ix)
    	ld	c,a
    	ld	a,b
    	adc	a,11(ix)
    	ld	b,a
    	ld	l,12(ix)
    	ld	h,13(ix)
    	add	hl,bc
    00115$:
    	pop	ix
    	ret
    Итоговая оценка- 7/10. Умное распространение констант, сжатие переходов, приемлимый заголовок цикла, различная оптимизация, но повсеместное использование индексного регистра для хранения глобальных переменных все портит. Надо будет проверить как он себя ведет на статических переменных и возможно ли убрать работу с индексными регистрами. Если получится, то данный компилятор можно рекомендовать к применению!

  9. #78

    Регистрация
    14.01.2005
    Адрес
    Таганрог, Россия
    Сообщений
    4,286
    Спасибо Благодарностей отдано 
    9
    Спасибо Благодарностей получено 
    91
    Поблагодарили
    39 сообщений
    Mentioned
    8 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Последний из имеющихся пациент- z88dk. Порядком помучался пока заставил его генерить исходник ассемблера. Если попросить, вставляет в исходный текст строки на С, но честно предупреждает, что в таком случае некоторая оптимизация не получится. Я буду уточнять, в каких местах возникла разница.
    Использовался уровень оптимизации 2

    0.Пролог
    Его просто нет. Сразу идет код main.

    1. Тест на размножение констант и копий.
    Код:
    ;j4 = 2;
    	ld	hl,2	;const
    	ld	(_j4),hl
    ;if( i2 < j4 && i4 < j4 )
    ;нет размножения констант плюс функции для сравнения
    	ld	de,(_i2)
    	ld	hl,(_j4)
    	call	l_lt
    	jp	nc,i_4
    	ld	de,(_i4)
    	ld	hl,(_j4)
    	call	l_lt
    ;обратите внимание- использование коротких команд
    ;перехода
    ;но в то же время систему переходов можно (и нужно)
    ;было бы оптимизировать
    	jr	c,i_5_i_4
    .i_4
    	jp	i_3
    .i_5_i_4
    ;i2 = 2;
    	ld	hl,2	;const
    	ld	(_i2),hl
    ;j4 = k5;
    .i_3
    ;та же картина
    	ld	hl,(_k5)
    	ld	(_j4),hl
    ;if( i2 < j4 && i4 < j4 )
    	ld	de,(_i2)
    	ld	hl,(_j4)
    	call	l_lt
    	jp	nc,i_7
    	ld	de,(_i4)
    	ld	hl,(_j4)
    	call	l_lt
    	jr	c,i_8_i_7
    .i_7
    	jp	i_6
    .i_8_i_7
    ;i5 = 3;
    	ld	hl,3	;const
    	ld	(_i5),hl
    .i_6
    2.Свертка констант
    Код:
    ;i3 = 1 + 2;
    ;свернул
    	ld	hl,3	;const
    	ld	(_i3),hl
    ;flt_1 = 2.4 + 6.3;
    ;оп-па! не свернул!
    	ld	hl,i_2+0
    	call	dldpsh
    	ld	hl,i_2+6
    	call	dload
    	call	dadd
    	ld	hl,_flt_1
    	call	dstore
    ;i2 = 5;
    ;загрузка константы
    	ld	hl,5	;const
    	ld	(_i2),hl
    ;j2 = i + 0;
    ;0 не стал прибавлять
    	ld	hl,(_i)
    	ld	(_j2),hl
    ;k2 = i / 1;
    ;а вот на 1 поделить не побрезговал....
    	ld	hl,(_i)
    	ld	de,1	;const
    	ex	de,hl
    	call	l_div
    	ld	(_k2),hl
    ;i4 = i * 1;
    ;и умножить тоже
    	ld	hl,(_i)
    	ld	de,1
    	call	l_mult
    	ld	(_i4),hl
    ;i5 = i * 0;
    ;и на ноль тоже...
    	ld	hl,(_i)
    	ld	de,0
    	call	l_mult
    	ld	(_i5),hl
    ;printf( "This compiler handles divide-by-zero as              an error\n");
    ;да, он прохавал деление на нулевую константу
    ;параметры через стек
    	ld	hl,i_1+0
    	push	hl
    	call	_printf
    	pop	bc
    ;flt_3 = 2.4 / 1.0;
    ;мрак... на 1 тоже делит, да еще и в реальном времени...
    	ld	hl,i_2+0
    	call	dldpsh
    	ld	hl,i_2+12
    	call	dload
    	call	ddiv
    	ld	hl,_flt_3
    	call	dstore
    ;flt_4 = 1.0 + 0.0000001;
    ;без слов...
    	ld	hl,i_2+12
    	call	dldpsh
    	ld	hl,i_2+18
    	call	dload
    	call	dadd
    	ld	hl,_flt_4
    	call	dstore
    ;flt_5 = flt_6 * 0.0;
    ;...одни эмоции
    	ld	hl,_flt_6
    	call	dldpsh
    	ld	hl,i_2+24
    	call	dload
    	call	dmul
    	ld	hl,_flt_5
    	call	dstore
    ;flt_6 = flt_2 * flt_3;
    ;ну тут по другому никак
    	ld	hl,_flt_2
    	call	dldpsh
    	ld	hl,_flt_3
    	call	dload
    	call	dmul
    	ld	hl,_flt_6
    	call	dstore
    3.Лишнее присваивание
    Код:
    ;k3 = 1;
    	ld	hl,1	;const
    	ld	(_k3),hl
    ;k3 = 1;
    ;в худших традициях...
    	ld	hl,1	;const
    	ld	(_k3),hl
    4.Снижение мощности
    Код:
    ;k2 = 4 * j5;
    ;не заметил возможности умножения "малой кровью"
    	ld	hl,(_j5)
    	ld	de,4
    	call	l_mult
    	ld	(_k2),hl
    ;for( i = 0; i <= 5; i++ )
    ;реализация цикла for в лучших традициях!
    	ld	hl,0	;const
    	ld	(_i),hl
    	jp	i_11
    .i_9
    ;ivector4[ i ] = i * 2;
    ;хорошо что хоть догадался сдвигами умножать на размер
    ;типа, а не функциями, но лишние операции со стеком
    	ld	hl,_ivector4
    	push	hl
    	ld	hl,(_i)
    	add	hl,hl
    	pop	de
    	add	hl,de
    	push	hl
    	ld	hl,(_i)
    	add	hl,hl
    	pop	de
    	call	l_pint
    ;классика!
    	ld	hl,(_i)
    	inc	hl
    	ld	(_i),hl
    	dec	hl
    .i_11
    ;мрак...
    	ld	hl,(_i)
    	ld	de,5	;const
    	ex	de,hl
    	call	l_le
    	jp	c,i_9
    .i_10
    5.Простой цикл
    Код:
    ;j5 = 0;
    	ld	hl,0	;const
    	ld	(_j5),hl
    ;k5 = 10000;
    	ld	hl,10000	;const
    	ld	(_k5),hl
    ;do {
    .i_14
    ;k5 = k5 - 1;
    ;распознал вычитание единицы!
    	ld	hl,(_k5)
    	dec	hl
    	ld	(_k5),hl
    ;j5 = j5 + 1;
    ;и ее прибавление
    	ld	hl,(_j5)
    	inc	hl
    	ld	(_j5),hl
    ;i5 = (k5 * 3) / (j5 * 5);
    ;ну ведь можешь же умножать когда хочешь!
    	ld	hl,(_k5)
    	ld	b,h
    	ld	c,l
    	add	hl,bc
    	add	hl,bc
    	push	hl
    	ld	hl,(_j5)
    	ld	b,h
    	ld	c,l
    	add	hl,hl
    	add	hl,hl
    	add	hl,bc
    	pop	de
    	call	l_div
    	ld	(_i5),hl
    ;} while ( k5 > 0 );
    .i_12
    ;оригинальная проверка на конец цикла
    	ld	hl,(_k5)
    	xor	a
    	or	h
    	jp	m,i_13
    	or	l
    	jp	nz,i_14
    .i_13
    6.Управление переменной индукции цикла
    Код:
    ;for( i = 0; i < 100; i++ )
    	ld	hl,0	;const
    	ld	(_i),hl
    	jp	i_17
    .i_15
    ;ivector5[ i * 2 + 3 ] = 5;
    ;специфично, но в целом терпимо
    	ld	hl,_ivector5
    	push	hl
    	ld	hl,(_i)
    	add	hl,hl
    	inc	hl
    	inc	hl
    	inc	hl
    	add	hl,hl
    	pop	de
    	add	hl,de
    	ld	(hl),#(5 % 256)
    	inc	hl
    	ld	(hl),#(5 / 256)
    	ld	hl,(_i)
    	inc	hl
    	ld	(_i),hl
    ;а это зачем???
    	dec	hl
    .i_17
    ;оптимизацию for не доделали...
    	ld	hl,(_i)
    	ld	de,100	;const
    	ex	de,hl
    	call	l_lt
    	jp	c,i_15
    .i_16
    7.Глубокие подвыражения
    Код:
    ;if( i < 10 )
    ;хреново сравнивает!
    	ld	hl,(_i)
    	ld	de,10	;const
    	ex	de,hl
    	call	l_lt
    	jp	nc,i_18
    ;j5 = i5 + i2;
    ;зато хоть складывает нормально
    	ld	de,(_i5)
    	ld	hl,(_i2)
    	add	hl,de
    	ld	(_j5),hl
    ;else
    	jp	i_19
    .i_18
    ;k5 = i5 + i2;
    ;выделения подвыражений нет
    	ld	de,(_i5)
    	ld	hl,(_i2)
    	add	hl,de
    	ld	(_k5),hl
    .i_19
    8.Генерация адреса переменной с константным индексом, размножение копий и регистров
    Код:
    ;ivector[ 0 ] = 1;
    ;правильно
    	ld	hl,1	;const
    	ld	(_ivector),hl
    ;ivector[ i2 ] = 2;
    ;лишние операции со стеком, простая перестановка дала
    ;бы прирост эффективности
    	ld	hl,_ivector
    	push	hl
    	ld	hl,(_i2)
    	add	hl,hl
    	pop	de
    	add	hl,de
    	ld	de,2	;const
    	ex	de,hl
    ;да что за мрак!
    	call	l_pint
    ;ivector[ i2 ] = 2;
    ;не воспользовался результатом предыдущей операции
    	ld	hl,_ivector
    	push	hl
    	ld	hl,(_i2)
    	add	hl,hl
    	pop	de
    	add	hl,de
    	ld	de,2	;const
    	ex	de,hl
    	call	l_pint
    ;ivector[ 2 ] = 3;
    ;тут все правильно
    	ld	hl,3	;const
    	ld	(_ivector+4),hl
    9.Удаление общих подвыражений
    Код:
    ;if(( h3 + k3 ) < 0 || ( h3 + k3 ) > 5 )
    ;хорошее начало, но дальше не очень
    	ld	de,(_h3)
    	ld	hl,(_k3)
    	add	hl,de
    	ld	de,0	;const
    	ex	de,hl
    	call	l_lt
    	jp	c,i_21
    ;не используются результаты...
    	ld	de,(_h3)
    	ld	hl,(_k3)
    	add	hl,de
    	ld	de,5	;const
    	ex	de,hl
    	call	l_gt
    	jp	nc,i_20
    .i_21
    ;printf("Common subexpression elimination\n");
    ;параметры через стек
    	ld	hl,i_1+63
    	push	hl
    	call	_printf
    	pop	bc
    ;else {
    	jp	i_23
    .i_20
    ;m3 = ( h3 + k3 ) / i3;
    ;совсем не используются...
    	ld	de,(_h3)
    	ld	hl,(_k3)
    	add	hl,de
    	ex	de,hl
    	ld	hl,(_i3)
    	call	l_div
    	ld	(_m3),hl
    ;g3 = i3 + (h3 + k3);
    	ld	hl,(_i3)
    	push	hl
    	ld	de,(_h3)
    	ld	hl,(_k3)
    	add	hl,de
    	pop	de
    	add	hl,de
    	ld	(_g3),hl
    ;}
    .i_23
    10.Вынесение инвариантного кода
    Код:
    ;for( i4 = 0; i4 <= 2; i4++)
    	ld	hl,0	;const
    	ld	(_i4),hl
    	jp	i_26
    .i_24
    ;ivector2[ i4 ] = j * k;
    ;обычная обработка индекса массива
    	ld	de,_ivector2
    	ld	hl,(_i4)
    	add	hl,de
    	push	hl
    ;но вынесения кода нет
    	ld	de,(_j)
    	ld	hl,(_k)
    	call	l_mult
    	pop	de
    	ld	a,l
    	ld	(de),a
    	ld	hl,(_i4)
    	inc	hl
    	ld	(_i4),hl
    	dec	hl
    .i_26
    	ld	hl,(_i4)
    	ld	de,2	;const
    	ex	de,hl
    	call	l_le
    	jp	c,i_24
    .i_25

  10. #79

    Регистрация
    14.01.2005
    Адрес
    Таганрог, Россия
    Сообщений
    4,286
    Спасибо Благодарностей отдано 
    9
    Спасибо Благодарностей получено 
    91
    Поблагодарили
    39 сообщений
    Mentioned
    8 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    11.Вызов функции с аргументами. Определение недостижимого кода
    Код:
    ;dead_code( 1, "This line should not be printed" );
    ;параметры через стек, слева направо (хотя должно быть наоборот...)
    	ld	hl,1	;const
    	push	hl
    	ld	hl,i_1+97
    	push	hl
    	call	_dead_code
    	pop	bc
    	pop	bc
    Код:
    ;void dead_code( a, b )
    ;int a;
    ;char *b;
    
    ._dead_code
    ;{
    ;int idead_store;
    ;idead_store = a;
    	ld	hl,6-2	;const
    	add	hl,sp
    	call	l_gint	;
    	push	hl
    ;if( 0 )
    ;переход выполняет
    	jp	i_27
    ;printf( "%s\n", b );
    ;но код для пустышки генерит!
    	ld	hl,i_1+129
    	push	hl
    	ld	hl,6	;const
    	add	hl,sp
    	call	l_gint	;
    	push	hl
    	call	_printf
    	pop	bc
    	pop	bc
    ;}
    .i_27
    	pop	bc
    	ret
    12.Вызов функции без аргументов. Исключение циклов
    Код:
    	call	_unnecessary_loop
    Код:
    ;void unnecessary_loop()
    ;{
    ._unnecessary_loop
    ;int x;
    ;x = 0;
    ;регистровая переменная- хорошо
    	ld	hl,0	;const
    ;но в стеке- плохо
    	push	hl
    ;for( i = 0; i < 5; i++ )
    	ld	hl,0	;const
    	ld	(_i),hl
    	jp	i_30
    .i_28
    ;k5 = x + j5;
    ;прикольно :)
    	pop	de
    	push	de
    	ld	hl,(_j5)
    	add	hl,de
    	ld	(_k5),hl
    	ld	hl,(_i)
    	inc	hl
    	ld	(_i),hl
    	dec	hl
    .i_30
    	ld	hl,(_i)
    	ld	de,5	;const
    	ex	de,hl
    	call	l_lt
    	jp	c,i_28
    .i_29
    ;}
    	pop	bc
    	ret
    13. Слияние заголовков циклов
    Код:
    ;void loop_jamming( x )
    ;int x;
    ._loop_jamming
    ;{
    ;for( i = 0; i < 5; i++ )
    	ld	hl,0	;const
    	ld	(_i),hl
    	jp	i_33
    .i_31
    ;k5 = x + j5 * i;
    ;наверное ошибка- на стеке на один параметр меньше
    	pop	bc
    	pop	hl
    	push	hl
    	push	bc
    	push	hl
    	ld	de,(_j5)
    	ld	hl,(_i)
    	call	l_mult
    	pop	de
    	add	hl,de
    	ld	(_k5),hl
    	ld	hl,(_i)
    	inc	hl
    	ld	(_i),hl
    	dec	hl
    .i_33
    	ld	hl,(_i)
    	ld	de,5	;const
    	ex	de,hl
    	call	l_lt
    	jp	c,i_31
    .i_32
    ;for( i = 0; i < 5; i++ )
    ;второй цикл точная копия первого
    	ld	hl,0	;const
    	ld	(_i),hl
    	jp	i_36
    .i_34
    ;i5 = x * k5 * i;
    	pop	bc
    	pop	hl
    	push	hl
    	push	bc
    	ex	de,hl
    	ld	hl,(_k5)
    	call	l_mult
    	ex	de,hl
    	ld	hl,(_i)
    	call	l_mult
    	ld	(_i5),hl
    	ld	hl,(_i)
    	inc	hl
    	ld	(_i),hl
    	dec	hl
    .i_36
    	ld	hl,(_i)
    	ld	de,5	;const
    	ex	de,hl
    	call	l_lt
    	jp	c,i_34
    .i_35
    ;}
    	ret
    14.Разворачивание циклов
    Код:
    ;void loop_unrolling( x )
    ;int x;
    ._loop_unrolling
    ;{
    ;for( i = 0; i < 6; i++ )
    	ld	hl,0	;const
    	ld	(_i),hl
    	jp	i_39
    .i_37
    ;ivector4[ i ] = 0;
    ;нет разворота, да и загрузка достаточно тяжела
    	ld	hl,_ivector4
    	push	hl
    	ld	hl,(_i)
    	add	hl,hl
    	pop	de
    	add	hl,de
    	ld	(hl),#(0 % 256)
    	inc	hl
    	ld	(hl),#(0 / 256)
    	ld	hl,(_i)
    	inc	hl
    	ld	(_i),hl
    	dec	hl
    .i_39
    	ld	hl,(_i)
    	ld	de,6	;const
    	ex	de,hl
    	call	l_lt
    	jp	c,i_37
    .i_38
    ;}
    	ret
    15.Сжатие цепочки переходов
    Код:
    ;int jump_compression( i, j, k, l, m )
    ;int i, j, k, l, m;
    ._jump_compression
    ;{
    ;beg_1:
    .i_40
    ;if( i < j )
    ;вот тут бы не помешали индексные регистры, да не
    ;используются совсем...
    	ld	hl,10	;const
    	add	hl,sp
    	ld	e,(hl)
    	inc	hl
    	ld	d,(hl)
    	push	de
    	ld	hl,10	;const
    	add	hl,sp
    	call	l_gint	;
    	pop	de
    	call	l_lt
    	jp	nc,i_41
    ;{
    ;if( j < k )
    	ld	hl,8	;const
    	add	hl,sp
    	ld	e,(hl)
    	inc	hl
    	ld	d,(hl)
    	push	de
    	ld	hl,8	;const
    	add	hl,sp
    	call	l_gint	;
    	pop	de
    	call	l_lt
    	jp	nc,i_42
    ;{
    ;if( k < l )
    	ld	hl,6	;const
    	add	hl,sp
    	ld	e,(hl)
    	inc	hl
    	ld	d,(hl)
    	push	de
    	ld	hl,6	;const
    	add	hl,sp
    	call	l_gint	;
    	pop	de
    	call	l_lt
    	jp	nc,i_43
    ;{
    ;if( l < m )
    	ld	hl,4	;const
    	add	hl,sp
    	ld	e,(hl)
    	inc	hl
    	ld	d,(hl)
    	push	de
    	ld	hl,4	;const
    	add	hl,sp
    	call	l_gint	;
    	pop	de
    	call	l_lt
    	jp	nc,i_44
    ;l += m;
    	ld	hl,4	;const
    	add	hl,sp
    	push	hl
    	ld	e,(hl)
    	inc	hl
    	ld	d,(hl)
    	push	de
    	ld	hl,6	;const
    	add	hl,sp
    	call	l_gint	;
    	pop	de
    	add	hl,de
    	pop	de
    	call	l_pint
    ;else
    	jp	i_45
    .i_44
    ;goto end_1;
    ;нет оптимизации переходов
    	jp	i_46
    .i_45
    ;}
    ;else
    	jp	i_47
    .i_43
    ;k += l;
    	ld	hl,6	;const
    	add	hl,sp
    	push	hl
    	ld	e,(hl)
    	inc	hl
    	ld	d,(hl)
    	push	de
    	ld	hl,8	;const
    	add	hl,sp
    	call	l_gint	;
    	pop	de
    	add	hl,de
    	pop	de
    	call	l_pint
    .i_47
    ;}
    ;else
    	jp	i_48
    .i_42
    ;{
    ;j += k;
    	ld	hl,8	;const
    	add	hl,sp
    	push	hl
    	ld	e,(hl)
    	inc	hl
    	ld	d,(hl)
    	push	de
    	ld	hl,10	;const
    	add	hl,sp
    	call	l_gint	;
    	pop	de
    	add	hl,de
    	pop	de
    	call	l_pint
    ;end_1:
    .i_46
    .i_49
    ;goto beg_1;
    	jp	i_40
    ;}
    .i_48
    ;}
    ;else
    	jp	i_50
    .i_41
    ;i += j;
    	ld	hl,10	;const
    	add	hl,sp
    	push	hl
    	ld	e,(hl)
    	inc	hl
    	ld	d,(hl)
    	push	de
    	ld	hl,12	;const
    	add	hl,sp
    	call	l_gint	;
    	pop	de
    	add	hl,de
    	pop	de
    	call	l_pint
    .i_50
    ;return( i + j + k + l + m );
    	ld	hl,10	;const
    	add	hl,sp
    	ld	e,(hl)
    	inc	hl
    	ld	d,(hl)
    	push	de
    	ld	hl,10	;const
    	add	hl,sp
    	call	l_gint	;
    	pop	de
    	add	hl,de
    	ex	de,hl
    	ld	hl,8-2	;const
    	add	hl,sp
    	call	l_gint	;
    	add	hl,de
    	ex	de,hl
    	ld	hl,6-2	;const
    	add	hl,sp
    	call	l_gint	;
    	add	hl,de
    	ex	de,hl
    	ld	hl,4-2	;const
    	add	hl,sp
    	call	l_gint	;
    	add	hl,de
    	ret
    ;}
    Итоговая оценка- 5/10. Туповатый компилятор, на который изредка находит озарение и он генерит неплохой код. К применению не рекомендуется...

  11. #80

    Регистрация
    06.05.2006
    Адрес
    Ливны, Орловская обл
    Сообщений
    1,169
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    0
    Поблагодарили
    0 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Спасибо, интересное исследование. Значит sdcc... Но вот меня смущает, что на sdcc.sf.net постоянно упоминается "freeware", несмотря на его GPL'ность.
    А по поводу переменных, наверное в реальных проектах будет много глобальных статических, чтобы компилятор их просто клал в память, не извращаясь со стеком или IX/IY.

Страница 8 из 19 ПерваяПервая ... 456789101112 ... ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •