URL
https://opencores.org/ocsvn/copyblaze/copyblaze/trunk
Subversion Repositories copyblaze
[/] [copyblaze/] [trunk/] [copyblaze/] [sw/] [tools/] [comp/] [pbcc/] [sdcc-3.1.0-pblaze_[-NaurbB].patch] - Rev 51
Compare with Previous | Blame | View Log
diff -NaurbB sdcc-src-3.1.0/Makefile.common.in sdcc-src-3.1.0-pblaze/Makefile.common.in --- sdcc-src-3.1.0/Makefile.common.in 2011-10-20 11:10:56.000000000 +0200 +++ sdcc-src-3.1.0-pblaze/Makefile.common.in 2011-12-04 13:58:18.197756400 +0100 @@ -51,6 +51,7 @@ OPT_DISABLE_Z180 = @OPT_DISABLE_Z180@ OPT_DISABLE_R2K = @OPT_DISABLE_R2K@ OPT_DISABLE_GBZ80 = @OPT_DISABLE_GBZ80@ +OPT_DISABLE_PBLAZE = @OPT_DISABLE_PBLAZE@ OPT_DISABLE_UCSIM = @OPT_DISABLE_UCSIM@ OPT_DISABLE_DEVICE_LIB= @OPT_DISABLE_DEVICE_LIB@ diff -NaurbB sdcc-src-3.1.0/configure sdcc-src-3.1.0-pblaze/configure --- sdcc-src-3.1.0/configure 2011-10-25 20:43:54.000000000 +0200 +++ sdcc-src-3.1.0-pblaze/configure 2011-12-05 22:37:52.945707300 +0100 @@ -620,6 +620,7 @@ OPT_DISABLE_Z180 OPT_DISABLE_Z80 OPT_DISABLE_MCS51 +OPT_DISABLE_PBLAZE non_free_lib_dir_suffix lib_dir_suffix non_free_include_dir_suffix @@ -716,6 +717,7 @@ enable_hc08_port enable_avr_port enable_xa51_port +enable_pblaze_port enable_ucsim enable_device_lib enable_packihx @@ -1373,6 +1375,7 @@ --disable-pic14-port Excludes the PIC14 port --disable-pic16-port Excludes the PIC16 port --disable-hc08-port Excludes the HC08 port + --disable-pblaze-port Excludes the PBLAZE port --enable-avr-port Includes the AVR port (disabled by default) --enable-xa51-port Includes the XA51 port (disabled by default) --disable-ucsim Disables configuring and building of ucsim @@ -6580,6 +6583,32 @@ + # Check whether --enable-pblaze-port was given. +if test "${enable_pblaze_port+set}" = set; then : + enableval=$enable_pblaze_port; +fi + + + if test "$enable_pblaze_port" = "no"; then + OPT_DISABLE_PBLAZE=1 + else + enable_pblaze_port="yes" + OPT_DISABLE_PBLAZE=0 + fi + + +cat >>confdefs.h <<_ACEOF +#define OPT_DISABLE_PBLAZE $OPT_DISABLE_PBLAZE +_ACEOF + + + + echo pblaze >>ports.all + if test $OPT_DISABLE_PBLAZE = 0; then + echo pblaze >>ports.build + fi + + # Check whether --enable-ucsim was given. if test "${enable_ucsim+set}" = set; then : enableval=$enable_ucsim; @@ -7068,6 +7097,10 @@ fi +if test $OPT_DISABLE_PBLAZE = 0; then + ac_config_files="$ac_config_files src/pblaze/Makefile" +fi + if test $OPT_DISABLE_Z80 = 0 || test $OPT_DISABLE_Z180 = 0; then ac_config_files="$ac_config_files sdas/asz80/Makefile" @@ -7797,6 +7830,7 @@ "src/hc08/Makefile") CONFIG_FILES="$CONFIG_FILES src/hc08/Makefile" ;; "sdas/as6808/Makefile") CONFIG_FILES="$CONFIG_FILES sdas/as6808/Makefile" ;; "device/lib/hc08/Makefile") CONFIG_FILES="$CONFIG_FILES device/lib/hc08/Makefile" ;; + "src/pblaze/Makefile") CONFIG_FILES="$CONFIG_FILES src/pblaze/Makefile" ;; "src/mcs51/Makefile") CONFIG_FILES="$CONFIG_FILES src/mcs51/Makefile" ;; "sdas/as8051/Makefile") CONFIG_FILES="$CONFIG_FILES sdas/as8051/Makefile" ;; "device/lib/mcs51/Makefile") CONFIG_FILES="$CONFIG_FILES device/lib/mcs51/Makefile" ;; @@ -8805,6 +8839,7 @@ z80 ${enable_z80_port} z180 ${enable_z180_port} r2k ${enable_r2k_port} + pblaze ${enable_pblaze_port} Disable packihx: ${OPT_DISABLE_PACKIHX} Disable ucsim: ${OPT_DISABLE_UCSIM} @@ -8865,6 +8900,7 @@ z80 ${enable_z80_port} z180 ${enable_z180_port} r2k ${enable_r2k_port} + pblaze ${enable_pblaze_port} Disable packihx: ${OPT_DISABLE_PACKIHX} Disable ucsim: ${OPT_DISABLE_UCSIM} diff -NaurbB sdcc-src-3.1.0/configure.in sdcc-src-3.1.0-pblaze/configure.in --- sdcc-src-3.1.0/configure.in 2011-10-25 20:43:54.000000000 +0200 +++ sdcc-src-3.1.0-pblaze/configure.in 2011-12-04 14:42:23.262045400 +0100 @@ -815,6 +815,7 @@ AC_DO_PORT(pic14, pic14, PIC14, [Excludes the PIC14 port]) AC_DO_PORT(pic16, pic16, PIC16, [Excludes the PIC16 port]) AC_DO_PORT(hc08, hc08, HC08, [Excludes the HC08 port]) +AC_DO_PORT(pblaze, pblaze, PBLAZE, [Excludes the PBLAZE port]) # Unsupported targets AC_DO_PORT_ENABLER(avr, avr, AVR, [Includes the AVR port (disabled by default)]) @@ -906,6 +907,10 @@ AC_CONFIG_FILES([src/z80/Makefile]) fi +if test $OPT_DISABLE_PBLAZE = 0; then + AC_CONFIG_FILES([src/pblaze/Makefile]) +fi + if test $OPT_DISABLE_Z80 = 0 || test $OPT_DISABLE_Z180 = 0; then AC_CONFIG_FILES([sdas/asz80/Makefile]) test $OPT_DISABLE_DEVICE_LIB = 0 && AC_CONFIG_FILES([device/lib/z80/Makefile @@ -991,6 +996,7 @@ z80 ${enable_z80_port} z180 ${enable_z180_port} r2k ${enable_r2k_port} + pblaze ${enable_pblaze_port} Disable packihx: ${OPT_DISABLE_PACKIHX} Disable ucsim: ${OPT_DISABLE_UCSIM} diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/asm.c sdcc-src-3.1.0-pblaze/device/examples/pblaze/asm.c --- sdcc-src-3.1.0/device/examples/pblaze/asm.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/asm.c 2011-08-23 15:57:26.000000000 +0200 @@ -0,0 +1,17 @@ +// test of inserted asm code into C code +int i; + +/* +asm +ENABLE_INTERRUPT; +endasm +*/ + +int main(void) +{ +__asm +INPUT s0 +__endasm; +i = 10; +return i; +} \ No newline at end of file diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/build.bat sdcc-src-3.1.0-pblaze/device/examples/pblaze/build.bat --- sdcc-src-3.1.0/device/examples/pblaze/build.bat 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/build.bat 2011-12-06 08:43:41.526003500 +0100 @@ -0,0 +1,8 @@ +@REM Compile-only (no assembling and linking) +..\..\..\bin\sdcc.exe %1 -mpblaze -S -I"..\..\..\device\include\pblaze" + +@REM Compile and assemble only (no linking) +@REM ..\..\bin\sdcc.exe %1 -mpblaze -c -I"..\..\device\include\pblaze" + +@REM Compile, assemble and link +@REM ..\..\bin\sdcc.exe %1 -mpblaze -I"..\..\device\include\pblaze" \ No newline at end of file diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/demo.c sdcc-src-3.1.0-pblaze/device/examples/pblaze/demo.c --- sdcc-src-3.1.0/device/examples/pblaze/demo.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/demo.c 2011-08-23 15:57:26.000000000 +0200 @@ -0,0 +1,42 @@ +//#include <stdio.h> + +void __port_write(char port, char arg) { } +char __port_read(char port) { } +void __nop() { } + +#define LCD_wr(arg) __port_write(0x01, (arg)) +#define LCD_rd() __port_read(0x01) +#define LCD_busy() (LCD_rd() & 0x80) == 0x80 + +void delay_ms(int ms) +{ + int i; + for (;;) { + for (i=0; i < 10000; i++) __nop(); + } +} + +void LCD_init() +{ + LCD_wr(0x42); + while (LCD_rd()) { __nop();} + LCD_wr(0x43); + delay_ms(10); + LCD_wr(0x44); + LCD_wr(0x45); +} + +void LCD_write(char ch) +{ + LCD_wr(0x46); + LCD_wr(0x47); +} + +int main(void) { + char ch = 0x31; + LCD_init(); + while (1) { + LCD_write(ch); + delay_ms(1000); + } +} diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/expected/test10.kcpsm.psm sdcc-src-3.1.0-pblaze/device/examples/pblaze/expected/test10.kcpsm.psm --- sdcc-src-3.1.0/device/examples/pblaze/expected/test10.kcpsm.psm 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/expected/test10.kcpsm.psm 2011-08-23 15:57:26.000000000 +0200 @@ -0,0 +1,213 @@ +;-------------------------------------------------------- +; File Created by SDCC : free open source ANSI-C Compiler +; Version 3.0.1 #6227 (Feb 20 2011) (Linux) +; This file was generated Fri Apr 22 14:06:05 2011 +;-------------------------------------------------------- +;-------------------------------------------------------- +; global & static initialisations +;-------------------------------------------------------- + CONSTANT _numbers_19, 00 + CONSTANT _numbers_18, 01 + CONSTANT _numbers_17, 02 + CONSTANT _numbers_16, 03 + CONSTANT _numbers_15, 04 + CONSTANT _numbers_14, 05 + CONSTANT _numbers_13, 06 + CONSTANT _numbers_12, 07 + CONSTANT _numbers_11, 08 + CONSTANT _numbers_10, 09 + CONSTANT _numbers_9, 0a + CONSTANT _numbers_8, 0b + CONSTANT _numbers_7, 0c + CONSTANT _numbers_6, 0d + CONSTANT _numbers_5, 0e + CONSTANT _numbers_4, 0f + CONSTANT _numbers_3, 10 + CONSTANT _numbers_2, 11 + CONSTANT _numbers_1, 12 + CONSTANT _numbers_0, 13 + +;------------------------------------------------------------ +;Allocation info for local variables in function 'main' +;------------------------------------------------------------ +;------------------------------------------------------------ + ; test10.c:5: volatile short numbers[ARRAY_SIZE] = {9,8,7,6,5,4,3,2,1,0}; + LOAD s0, _numbers_19 + LOAD s1, 00 + STORE s1, (s0) + ADD s0, 01 + LOAD s1, 09 + STORE s1, (s0) + LOAD s0, _numbers_19 + ADD s0, 02 + LOAD s1, 00 + STORE s1, (s0) + ADD s0, 01 + LOAD s1, 08 + STORE s1, (s0) + LOAD s0, _numbers_19 + ADD s0, 04 + LOAD s1, 00 + STORE s1, (s0) + ADD s0, 01 + LOAD s1, 07 + STORE s1, (s0) + LOAD s0, _numbers_19 + ADD s0, 06 + LOAD s1, 00 + STORE s1, (s0) + ADD s0, 01 + LOAD s1, 06 + STORE s1, (s0) + LOAD s0, _numbers_19 + ADD s0, 08 + LOAD s1, 00 + STORE s1, (s0) + ADD s0, 01 + LOAD s1, 05 + STORE s1, (s0) + LOAD s0, _numbers_19 + ADD s0, 0a + LOAD s1, 00 + STORE s1, (s0) + ADD s0, 01 + LOAD s1, 04 + STORE s1, (s0) + LOAD s0, _numbers_19 + ADD s0, 0c + LOAD s1, 00 + STORE s1, (s0) + ADD s0, 01 + LOAD s1, 03 + STORE s1, (s0) + LOAD s0, _numbers_19 + ADD s0, 0e + LOAD s1, 00 + STORE s1, (s0) + ADD s0, 01 + LOAD s1, 02 + STORE s1, (s0) + LOAD s0, _numbers_19 + ADD s0, 10 + LOAD s1, 00 + STORE s1, (s0) + ADD s0, 01 + LOAD s1, 01 + STORE s1, (s0) + LOAD s0, _numbers_19 + ADD s0, 12 + LOAD s1, 00 + STORE s1, (s0) + ADD s0, 01 + LOAD s1, 00 + STORE s1, (s0) + LOAD sF, 3f + JUMP __sdcc_program_startup +;-------------------------------------------------------- +; Home +;-------------------------------------------------------- +__sdcc_program_startup: + CALL _main +; return from main will lock up +__sdcc_loop: + JUMP __sdcc_loop +;-------------------------------------------------------- +; code +;-------------------------------------------------------- +;------------------------------------------------------------ +;Allocation info for local variables in function 'main' +;------------------------------------------------------------ +;------------------------------------------------------------ +_main: + ; test10.c:7: void main() + ; test10.c:11: for (i = (ARRAY_SIZE - 1); i > 0; i--) + LOAD s0, 09 + LOAD s1, 00 +_L00107: + LOAD s2, 00 + COMPARE s2, s1 + JUMP C, _LC00101 + LOAD s2, 00 + COMPARE s2, s0 + JUMP C, _LC00101 + JUMP _L00119 +_LC00101: + ; test10.c:13: for (j = 1; j <= i; j++) +_L00116: + LOAD s2, 01 + LOAD s3, 00 +_L00103: + COMPARE s1, s3 + JUMP C, _L00118 + COMPARE s0, s2 + JUMP C, _L00118 + ; test10.c:15: if (numbers[j-1] > numbers[j]) + LOAD s4, _numbers_19 + LOAD s5, s2 + SUB s5, 01 + SL0 s5 + ADD s4, s5 + FETCH s6, (s4) + ADD s4, 01 + FETCH s7, (s4) + LOAD s4, _numbers_19 + LOAD s8, s2 + LOAD s9, s3 + SL0 s8 + SLA s9 + ADD s4, s8 + FETCH sA, (s4) + ADD s4, 01 + STORE s8, 14 + FETCH s8, (s4) + COMPARE sA, s6 + JUMP C, _LC00102 + COMPARE s8, s7 + JUMP C, _LC00102 + JUMP _L00105 +_LC00102: + ; test10.c:17: temp = numbers[j-1]; + LOAD s4, _numbers_19 + ADD s4, s5 + FETCH s6, (s4) + ADD s4, 01 + FETCH s7, (s4) + LOAD s4, s7 + LOAD s8, s6 + ; test10.c:18: numbers[j-1] = numbers[j]; + LOAD s6, _numbers_19 + ADD s6, s5 + LOAD s5, _numbers_19 + FETCH s7, 14 + ADD s5, s7 + FETCH sA, (s5) + ADD s5, 01 + STORE s4, 14 + FETCH s4, (s5) + STORE sA, (s6) + ADD s6, 01 + STORE s4, (s6) + ; test10.c:19: numbers[j] = temp; + LOAD s4, _numbers_19 + ADD s4, s7 + STORE s8, (s4) + ADD s4, 01 + FETCH s5, 14 + STORE s5, (s4) +_L00105: + ; test10.c:13: for (j = 1; j <= i; j++) + ADD s2, 01 + ADDCY s3, 00 + JUMP _L00103 +_L00118: +_L00109: + ; test10.c:11: for (i = (ARRAY_SIZE - 1); i > 0; i--) + SUB s0, 01 + SUBCY s1, 00 + JUMP _L00107 +_L00119: +_L00111: + RETURN +;-------------------------------------------------------- +; interrupt vector +;-------------------------------------------------------- diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/expected/test10.pblazeide.psm sdcc-src-3.1.0-pblaze/device/examples/pblaze/expected/test10.pblazeide.psm --- sdcc-src-3.1.0/device/examples/pblaze/expected/test10.pblazeide.psm 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/expected/test10.pblazeide.psm 2011-08-23 15:57:26.000000000 +0200 @@ -0,0 +1,213 @@ +;-------------------------------------------------------- +; File Created by SDCC : free open source ANSI-C Compiler +; Version 3.0.1 #6227 (Feb 20 2011) (Linux) +; This file was generated Fri Apr 22 14:08:53 2011 +;-------------------------------------------------------- +;-------------------------------------------------------- +; global & static initialisations +;-------------------------------------------------------- + _numbers_19 EQU $00 + _numbers_18 EQU $01 + _numbers_17 EQU $02 + _numbers_16 EQU $03 + _numbers_15 EQU $04 + _numbers_14 EQU $05 + _numbers_13 EQU $06 + _numbers_12 EQU $07 + _numbers_11 EQU $08 + _numbers_10 EQU $09 + _numbers_9 EQU $0a + _numbers_8 EQU $0b + _numbers_7 EQU $0c + _numbers_6 EQU $0d + _numbers_5 EQU $0e + _numbers_4 EQU $0f + _numbers_3 EQU $10 + _numbers_2 EQU $11 + _numbers_1 EQU $12 + _numbers_0 EQU $13 + +;------------------------------------------------------------ +;Allocation info for local variables in function 'main' +;------------------------------------------------------------ +;------------------------------------------------------------ + ; test10.c:5: volatile short numbers[ARRAY_SIZE] = {9,8,7,6,5,4,3,2,1,0}; + LOAD s0, _numbers_19 + LOAD s1, $00 + STORE s1, (s0) + ADD s0, $01 + LOAD s1, $09 + STORE s1, (s0) + LOAD s0, _numbers_19 + ADD s0, $02 + LOAD s1, $00 + STORE s1, (s0) + ADD s0, $01 + LOAD s1, $08 + STORE s1, (s0) + LOAD s0, _numbers_19 + ADD s0, $04 + LOAD s1, $00 + STORE s1, (s0) + ADD s0, $01 + LOAD s1, $07 + STORE s1, (s0) + LOAD s0, _numbers_19 + ADD s0, $06 + LOAD s1, $00 + STORE s1, (s0) + ADD s0, $01 + LOAD s1, $06 + STORE s1, (s0) + LOAD s0, _numbers_19 + ADD s0, $08 + LOAD s1, $00 + STORE s1, (s0) + ADD s0, $01 + LOAD s1, $05 + STORE s1, (s0) + LOAD s0, _numbers_19 + ADD s0, $0a + LOAD s1, $00 + STORE s1, (s0) + ADD s0, $01 + LOAD s1, $04 + STORE s1, (s0) + LOAD s0, _numbers_19 + ADD s0, $0c + LOAD s1, $00 + STORE s1, (s0) + ADD s0, $01 + LOAD s1, $03 + STORE s1, (s0) + LOAD s0, _numbers_19 + ADD s0, $0e + LOAD s1, $00 + STORE s1, (s0) + ADD s0, $01 + LOAD s1, $02 + STORE s1, (s0) + LOAD s0, _numbers_19 + ADD s0, $10 + LOAD s1, $00 + STORE s1, (s0) + ADD s0, $01 + LOAD s1, $01 + STORE s1, (s0) + LOAD s0, _numbers_19 + ADD s0, $12 + LOAD s1, $00 + STORE s1, (s0) + ADD s0, $01 + LOAD s1, $00 + STORE s1, (s0) + LOAD sF, $3f + JUMP __sdcc_program_startup +;-------------------------------------------------------- +; Home +;-------------------------------------------------------- +__sdcc_program_startup: + CALL _main +; return from main will lock up +__sdcc_loop: + JUMP __sdcc_loop +;-------------------------------------------------------- +; code +;-------------------------------------------------------- +;------------------------------------------------------------ +;Allocation info for local variables in function 'main' +;------------------------------------------------------------ +;------------------------------------------------------------ +_main: + ; test10.c:7: void main() + ; test10.c:11: for (i = (ARRAY_SIZE - 1); i > 0; i--) + LOAD s0, $09 + LOAD s1, $00 +_L00107: + LOAD s2, $00 + COMP s2, s1 + JUMP C, _LC00101 + LOAD s2, $00 + COMP s2, s0 + JUMP C, _LC00101 + JUMP _L00119 +_LC00101: + ; test10.c:13: for (j = 1; j <= i; j++) +_L00116: + LOAD s2, $01 + LOAD s3, $00 +_L00103: + COMP s1, s3 + JUMP C, _L00118 + COMP s0, s2 + JUMP C, _L00118 + ; test10.c:15: if (numbers[j-1] > numbers[j]) + LOAD s4, _numbers_19 + LOAD s5, s2 + SUB s5, $01 + SL0 s5 + ADD s4, s5 + FETCH s6, (s4) + ADD s4, $01 + FETCH s7, (s4) + LOAD s4, _numbers_19 + LOAD s8, s2 + LOAD s9, s3 + SL0 s8 + SLA s9 + ADD s4, s8 + FETCH sA, (s4) + ADD s4, $01 + STORE s8, 14 + FETCH s8, (s4) + COMP sA, s6 + JUMP C, _LC00102 + COMP s8, s7 + JUMP C, _LC00102 + JUMP _L00105 +_LC00102: + ; test10.c:17: temp = numbers[j-1]; + LOAD s4, _numbers_19 + ADD s4, s5 + FETCH s6, (s4) + ADD s4, $01 + FETCH s7, (s4) + LOAD s4, s7 + LOAD s8, s6 + ; test10.c:18: numbers[j-1] = numbers[j]; + LOAD s6, _numbers_19 + ADD s6, s5 + LOAD s5, _numbers_19 + FETCH s7, 14 + ADD s5, s7 + FETCH sA, (s5) + ADD s5, $01 + STORE s4, 14 + FETCH s4, (s5) + STORE sA, (s6) + ADD s6, $01 + STORE s4, (s6) + ; test10.c:19: numbers[j] = temp; + LOAD s4, _numbers_19 + ADD s4, s7 + STORE s8, (s4) + ADD s4, $01 + FETCH s5, 14 + STORE s5, (s4) +_L00105: + ; test10.c:13: for (j = 1; j <= i; j++) + ADD s2, $01 + ADDC s3, $00 + JUMP _L00103 +_L00118: +_L00109: + ; test10.c:11: for (i = (ARRAY_SIZE - 1); i > 0; i--) + SUB s0, $01 + SUBC s1, $00 + JUMP _L00107 +_L00119: +_L00111: + RET +;-------------------------------------------------------- +; interrupt vector +;-------------------------------------------------------- diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/expected/test6.kcpsm.psm sdcc-src-3.1.0-pblaze/device/examples/pblaze/expected/test6.kcpsm.psm --- sdcc-src-3.1.0/device/examples/pblaze/expected/test6.kcpsm.psm 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/expected/test6.kcpsm.psm 2011-08-23 15:57:26.000000000 +0200 @@ -0,0 +1,74 @@ +;-------------------------------------------------------- +; File Created by SDCC : free open source ANSI-C Compiler +; Version 3.0.1 #6227 (Feb 20 2011) (Linux) +; This file was generated Fri Apr 22 14:21:55 2011 +;-------------------------------------------------------- +;-------------------------------------------------------- +; global & static initialisations +;-------------------------------------------------------- + CONSTANT _val_0, 00 + CONSTANT _c_0, 01 + +;------------------------------------------------------------ +;Allocation info for local variables in function 'main' +;------------------------------------------------------------ +;------------------------------------------------------------ + ; test6.c:3: char __xdata val = 0; + LOAD s0, 00 + STORE s0, _val_0 + LOAD sF, 3f + JUMP __sdcc_program_startup +;-------------------------------------------------------- +; Home +;-------------------------------------------------------- +__sdcc_program_startup: + CALL _main +; return from main will lock up +__sdcc_loop: + JUMP __sdcc_loop +;-------------------------------------------------------- +; code +;-------------------------------------------------------- +;------------------------------------------------------------ +;Allocation info for local variables in function 'main' +;------------------------------------------------------------ +;------------------------------------------------------------ + ; test6.c:6: void interruptHandler() __interrupt +interruptHandler: + ; test6.c:8: val++; + STORE s0, (sF) + SUB sF, 01 + STORE s1, (sF) + SUB sF, 01 + FETCH s1, _val_0 + LOAD s0, s1 + ADD s0, 01 + ADD sF, 01 + FETCH s1, (sF) + ADD sF, 01 + FETCH s0, (sF) + STORE s0, _val_0 + RETURNI ENABLE +;------------------------------------------------------------ +;Allocation info for local variables in function 'main' +;------------------------------------------------------------ +;------------------------------------------------------------ +_main: + ; test6.c:11: void main() + ; test6.c:13: c = 0; + LOAD s0, 00 + ; test6.c:16: __endasm; + EINT +_L00106: +_L00102: + ; test6.c:20: c += 4; + ADD s0, 04 + JUMP _L00102 +_L00104: + STORE s0, _c_0 + RETURN +;-------------------------------------------------------- +; interrupt vector +;-------------------------------------------------------- + ADDRESS 3ff + JUMP interruptHandler diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/expected/test6.pblazeide.psm sdcc-src-3.1.0-pblaze/device/examples/pblaze/expected/test6.pblazeide.psm --- sdcc-src-3.1.0/device/examples/pblaze/expected/test6.pblazeide.psm 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/expected/test6.pblazeide.psm 2011-08-23 15:57:26.000000000 +0200 @@ -0,0 +1,74 @@ +;-------------------------------------------------------- +; File Created by SDCC : free open source ANSI-C Compiler +; Version 3.0.1 #6227 (Feb 20 2011) (Linux) +; This file was generated Fri Apr 22 14:22:57 2011 +;-------------------------------------------------------- +;-------------------------------------------------------- +; global & static initialisations +;-------------------------------------------------------- + _val_0 EQU $00 + _c_0 EQU $01 + +;------------------------------------------------------------ +;Allocation info for local variables in function 'main' +;------------------------------------------------------------ +;------------------------------------------------------------ + ; test6.c:3: char __xdata val = 0; + LOAD s0, $00 + STORE s0, _val_0 + LOAD sF, $3f + JUMP __sdcc_program_startup +;-------------------------------------------------------- +; Home +;-------------------------------------------------------- +__sdcc_program_startup: + CALL _main +; return from main will lock up +__sdcc_loop: + JUMP __sdcc_loop +;-------------------------------------------------------- +; code +;-------------------------------------------------------- +;------------------------------------------------------------ +;Allocation info for local variables in function 'main' +;------------------------------------------------------------ +;------------------------------------------------------------ + ; test6.c:6: void interruptHandler() __interrupt +interruptHandler: + ; test6.c:8: val++; + STORE s0, (sF) + SUB sF, $01 + STORE s1, (sF) + SUB sF, $01 + FETCH s1, _val_0 + LOAD s0, s1 + ADD s0, $01 + ADD sF, $01 + FETCH s1, (sF) + ADD sF, $01 + FETCH s0, (sF) + STORE s0, _val_0 + RETI ENABLE +;------------------------------------------------------------ +;Allocation info for local variables in function 'main' +;------------------------------------------------------------ +;------------------------------------------------------------ +_main: + ; test6.c:11: void main() + ; test6.c:13: c = 0; + LOAD s0, $00 + ; test6.c:16: __endasm; + EINT +_L00106: +_L00102: + ; test6.c:20: c += 4; + ADD s0, $04 + JUMP _L00102 +_L00104: + STORE s0, _c_0 + RET +;-------------------------------------------------------- +; interrupt vector +;-------------------------------------------------------- + ORG $3ff + JUMP interruptHandler diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/expected/test7.kcpsm.psm sdcc-src-3.1.0-pblaze/device/examples/pblaze/expected/test7.kcpsm.psm --- sdcc-src-3.1.0/device/examples/pblaze/expected/test7.kcpsm.psm 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/expected/test7.kcpsm.psm 2011-08-23 15:57:26.000000000 +0200 @@ -0,0 +1,149 @@ +;-------------------------------------------------------- +; File Created by SDCC : free open source ANSI-C Compiler +; Version 3.0.1 #6227 (Feb 20 2011) (Linux) +; This file was generated Fri Apr 22 14:05:13 2011 +;-------------------------------------------------------- +;-------------------------------------------------------- +; global & static initialisations +;-------------------------------------------------------- + CONSTANT _main_c_1_1_0, 00 + CONSTANT _main_d_1_1_0, 01 + CONSTANT _main_e_1_1_0, 02 + + LOAD sF, 3f + JUMP __sdcc_program_startup +;-------------------------------------------------------- +; Home +;-------------------------------------------------------- +__sdcc_program_startup: + CALL _main +; return from main will lock up +__sdcc_loop: + JUMP __sdcc_loop +;-------------------------------------------------------- +; code +;-------------------------------------------------------- +;------------------------------------------------------------ +;Allocation info for local variables in function 'main' +;------------------------------------------------------------ +;------------------------------------------------------------ +_main: + ; test7.c:3: void main() + ; test7.c:5: volatile unsigned char c = 1; + LOAD s0, 01 + STORE s0, _main_c_1_1_0 + ; test7.c:6: volatile unsigned char d = 1; + LOAD s0, 01 + STORE s0, _main_d_1_1_0 + ; test7.c:7: volatile unsigned char e = 15; + LOAD s0, 0f + STORE s0, _main_e_1_1_0 + ; test7.c:9: c <<= 4; + FETCH s0, _main_c_1_1_0 + SL0 s0 + SL0 s0 + SL0 s0 + SL0 s0 + STORE s0, _main_c_1_1_0 + ; test7.c:11: c >>= 3; + FETCH s0, _main_c_1_1_0 + SR0 s0 + SR0 s0 + SR0 s0 + STORE s0, _main_c_1_1_0 + ; test7.c:13: c |= c; + FETCH s0, _main_c_1_1_0 + FETCH s1, _main_c_1_1_0 + OR s1, s0 + STORE s1, _main_c_1_1_0 + ; test7.c:15: c |= d + 1; + FETCH s0, _main_d_1_1_0 + ADD s0, 01 + FETCH s1, _main_c_1_1_0 + OR s1, s0 + STORE s1, _main_c_1_1_0 + ; test7.c:17: c = c & d; + FETCH s0, _main_c_1_1_0 + FETCH s1, _main_d_1_1_0 + AND s0, s1 + STORE s0, _main_c_1_1_0 + ; test7.c:19: d = ~e; + FETCH s0, _main_e_1_1_0 + XOR s0, ff + STORE s0, _main_d_1_1_0 + ; test7.c:21: e = c ^ d; + FETCH s0, _main_d_1_1_0 + FETCH s1, _main_c_1_1_0 + XOR s1, s0 + STORE s1, _main_e_1_1_0 + ; test7.c:23: c = !c && d || e; + FETCH s0, _main_c_1_1_0 + LOAD s1, 00 + COMPARE s0, 00 + JUMP NZ, _LC00101 + LOAD s1, 01 +_LC00101: + COMPARE s1, 00 + JUMP NZ, _LC00102 + JUMP _L00108 +_LC00102: + FETCH s0, _main_d_1_1_0 + COMPARE s0, 00 + JUMP Z, _LC00103 + JUMP _L00109 +_LC00103: +_L00108: + LOAD s0, 00 + JUMP _L00110 +_L00109: + LOAD s0, 01 +_L00110: + COMPARE s0, 00 + JUMP Z, _LC00104 + JUMP _L00106 +_LC00104: + FETCH s0, _main_e_1_1_0 + COMPARE s0, 00 + JUMP Z, _LC00105 + JUMP _L00106 +_LC00105: + LOAD s0, 00 + JUMP _L00107 +_L00106: + LOAD s0, 01 +_L00107: + STORE s0, _main_c_1_1_0 + ; test7.c:24: c = c || e; + FETCH s0, _main_c_1_1_0 + COMPARE s0, 00 + JUMP Z, _LC00106 + JUMP _L00112 +_LC00106: + FETCH s0, _main_e_1_1_0 + COMPARE s0, 00 + JUMP Z, _LC00107 + JUMP _L00112 +_LC00107: + LOAD s0, 00 + JUMP _L00113 +_L00112: + LOAD s0, 01 +_L00113: + STORE s0, _main_c_1_1_0 + ; test7.c:26: if (!c) + FETCH s0, _main_c_1_1_0 + COMPARE s0, 00 + JUMP Z, _LC00108 + JUMP _L00103 +_LC00108: + ; test7.c:28: c = -e; + FETCH s0, _main_e_1_1_0 + LOAD s1, s0 + XOR s1, ff + ADD s1, 01 + STORE s1, _main_c_1_1_0 +_L00103: + RETURN +;-------------------------------------------------------- +; interrupt vector +;-------------------------------------------------------- diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/expected/test7.pblazeide.psm sdcc-src-3.1.0-pblaze/device/examples/pblaze/expected/test7.pblazeide.psm --- sdcc-src-3.1.0/device/examples/pblaze/expected/test7.pblazeide.psm 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/expected/test7.pblazeide.psm 2011-08-23 15:57:26.000000000 +0200 @@ -0,0 +1,149 @@ +;-------------------------------------------------------- +; File Created by SDCC : free open source ANSI-C Compiler +; Version 3.0.1 #6227 (Feb 20 2011) (Linux) +; This file was generated Fri Apr 22 14:09:05 2011 +;-------------------------------------------------------- +;-------------------------------------------------------- +; global & static initialisations +;-------------------------------------------------------- + _main_c_1_1_0 EQU $00 + _main_d_1_1_0 EQU $01 + _main_e_1_1_0 EQU $02 + + LOAD sF, $3f + JUMP __sdcc_program_startup +;-------------------------------------------------------- +; Home +;-------------------------------------------------------- +__sdcc_program_startup: + CALL _main +; return from main will lock up +__sdcc_loop: + JUMP __sdcc_loop +;-------------------------------------------------------- +; code +;-------------------------------------------------------- +;------------------------------------------------------------ +;Allocation info for local variables in function 'main' +;------------------------------------------------------------ +;------------------------------------------------------------ +_main: + ; test7.c:3: void main() + ; test7.c:5: volatile unsigned char c = 1; + LOAD s0, $01 + STORE s0, _main_c_1_1_0 + ; test7.c:6: volatile unsigned char d = 1; + LOAD s0, $01 + STORE s0, _main_d_1_1_0 + ; test7.c:7: volatile unsigned char e = 15; + LOAD s0, $0f + STORE s0, _main_e_1_1_0 + ; test7.c:9: c <<= 4; + FETCH s0, _main_c_1_1_0 + SL0 s0 + SL0 s0 + SL0 s0 + SL0 s0 + STORE s0, _main_c_1_1_0 + ; test7.c:11: c >>= 3; + FETCH s0, _main_c_1_1_0 + SR0 s0 + SR0 s0 + SR0 s0 + STORE s0, _main_c_1_1_0 + ; test7.c:13: c |= c; + FETCH s0, _main_c_1_1_0 + FETCH s1, _main_c_1_1_0 + OR s1, s0 + STORE s1, _main_c_1_1_0 + ; test7.c:15: c |= d + 1; + FETCH s0, _main_d_1_1_0 + ADD s0, $01 + FETCH s1, _main_c_1_1_0 + OR s1, s0 + STORE s1, _main_c_1_1_0 + ; test7.c:17: c = c & d; + FETCH s0, _main_c_1_1_0 + FETCH s1, _main_d_1_1_0 + AND s0, s1 + STORE s0, _main_c_1_1_0 + ; test7.c:19: d = ~e; + FETCH s0, _main_e_1_1_0 + XOR s0, $ff + STORE s0, _main_d_1_1_0 + ; test7.c:21: e = c ^ d; + FETCH s0, _main_d_1_1_0 + FETCH s1, _main_c_1_1_0 + XOR s1, s0 + STORE s1, _main_e_1_1_0 + ; test7.c:23: c = !c && d || e; + FETCH s0, _main_c_1_1_0 + LOAD s1, $00 + COMP s0, $00 + JUMP NZ, _LC00101 + LOAD s1, $01 +_LC00101: + COMP s1, $00 + JUMP NZ, _LC00102 + JUMP _L00108 +_LC00102: + FETCH s0, _main_d_1_1_0 + COMP s0, $00 + JUMP Z, _LC00103 + JUMP _L00109 +_LC00103: +_L00108: + LOAD s0, $00 + JUMP _L00110 +_L00109: + LOAD s0, $01 +_L00110: + COMP s0, $00 + JUMP Z, _LC00104 + JUMP _L00106 +_LC00104: + FETCH s0, _main_e_1_1_0 + COMP s0, $00 + JUMP Z, _LC00105 + JUMP _L00106 +_LC00105: + LOAD s0, $00 + JUMP _L00107 +_L00106: + LOAD s0, $01 +_L00107: + STORE s0, _main_c_1_1_0 + ; test7.c:24: c = c || e; + FETCH s0, _main_c_1_1_0 + COMP s0, $00 + JUMP Z, _LC00106 + JUMP _L00112 +_LC00106: + FETCH s0, _main_e_1_1_0 + COMP s0, $00 + JUMP Z, _LC00107 + JUMP _L00112 +_LC00107: + LOAD s0, $00 + JUMP _L00113 +_L00112: + LOAD s0, $01 +_L00113: + STORE s0, _main_c_1_1_0 + ; test7.c:26: if (!c) + FETCH s0, _main_c_1_1_0 + COMP s0, $00 + JUMP Z, _LC00108 + JUMP _L00103 +_LC00108: + ; test7.c:28: c = -e; + FETCH s0, _main_e_1_1_0 + LOAD s1, s0 + XOR s1, $ff + ADD s1, $01 + STORE s1, _main_c_1_1_0 +_L00103: + RET +;-------------------------------------------------------- +; interrupt vector +;-------------------------------------------------------- diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/expected/test8.kcpsm.psm sdcc-src-3.1.0-pblaze/device/examples/pblaze/expected/test8.kcpsm.psm --- sdcc-src-3.1.0/device/examples/pblaze/expected/test8.kcpsm.psm 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/expected/test8.kcpsm.psm 2011-08-23 15:57:26.000000000 +0200 @@ -0,0 +1,144 @@ +;-------------------------------------------------------- +; File Created by SDCC : free open source ANSI-C Compiler +; Version 3.0.1 #6227 (Feb 20 2011) (Linux) +; This file was generated Fri Apr 22 14:05:58 2011 +;-------------------------------------------------------- +;-------------------------------------------------------- +; global & static initialisations +;-------------------------------------------------------- + CONSTANT _main_c_1_1_0, 00 + + LOAD sF, 3f + JUMP __sdcc_program_startup +;-------------------------------------------------------- +; Home +;-------------------------------------------------------- +__sdcc_program_startup: + CALL _main +; return from main will lock up +__sdcc_loop: + JUMP __sdcc_loop +;-------------------------------------------------------- +; code +;-------------------------------------------------------- +;------------------------------------------------------------ +;Allocation info for local variables in function 'main' +;------------------------------------------------------------ +;------------------------------------------------------------ +_main: + ; test8.c:3: void main() + ; test8.c:5: volatile char c = 5; + LOAD s0, 05 + STORE s0, _main_c_1_1_0 + ; test8.c:8: switch(c) + FETCH s0, _main_c_1_1_0 + COMPARE s0, 0a + JUMP NZ, _LC00101 + JUMP _L00101 +_LC00101: + COMPARE s0, 0b + JUMP NZ, _LC00102 + JUMP _L00102 +_LC00102: + COMPARE s0, 0c + JUMP NZ, _LC00103 + JUMP _L00103 +_LC00103: + COMPARE s0, 0d + JUMP NZ, _LC00104 + JUMP _L00104 +_LC00104: + COMPARE s0, 0e + JUMP NZ, _LC00105 + JUMP _L00105 +_LC00105: + JUMP _L00106 + ; test8.c:10: case 10: c = 11; break; +_L00101: + LOAD s0, 0b + STORE s0, _main_c_1_1_0 + JUMP _L00107 + ; test8.c:11: case 11: c = 22; break; +_L00102: + LOAD s0, 16 + STORE s0, _main_c_1_1_0 + JUMP _L00107 + ; test8.c:12: case 12: c = 33; break; +_L00103: + LOAD s0, 21 + STORE s0, _main_c_1_1_0 + JUMP _L00107 + ; test8.c:13: case 13: c = 44; break; +_L00104: + LOAD s0, 2c + STORE s0, _main_c_1_1_0 + JUMP _L00107 + ; test8.c:14: case 14: c = 55; break; +_L00105: + LOAD s0, 37 + STORE s0, _main_c_1_1_0 + JUMP _L00107 + ; test8.c:15: default: c = 99; +_L00106: + LOAD s0, 63 + STORE s0, _main_c_1_1_0 + ; test8.c:17: } +_L00107: + ; test8.c:20: switch(c) + FETCH s0, _main_c_1_1_0 + COMPARE s0, 04 + JUMP NZ, _LC00106 + JUMP _L00111 +_LC00106: + COMPARE s0, 0a + JUMP NZ, _LC00107 + JUMP _L00108 +_LC00107: + COMPARE s0, 17 + JUMP NZ, _LC00108 + JUMP _L00109 +_LC00108: + COMPARE s0, 1f + JUMP NZ, _LC00109 + JUMP _L00110 +_LC00109: + COMPARE s0, 3b + JUMP NZ, _LC00110 + JUMP _L00112 +_LC00110: + JUMP _L00113 + ; test8.c:22: case 10: c = 11; break; +_L00108: + LOAD s0, 0b + STORE s0, _main_c_1_1_0 + JUMP _L00115 + ; test8.c:23: case 23: c = 22; break; +_L00109: + LOAD s0, 16 + STORE s0, _main_c_1_1_0 + JUMP _L00115 + ; test8.c:24: case 31: c = 33; break; +_L00110: + LOAD s0, 21 + STORE s0, _main_c_1_1_0 + JUMP _L00115 + ; test8.c:25: case 4: c = 44; break; +_L00111: + LOAD s0, 2c + STORE s0, _main_c_1_1_0 + JUMP _L00115 + ; test8.c:26: case 59: c = 55; break; +_L00112: + LOAD s0, 37 + STORE s0, _main_c_1_1_0 + JUMP _L00115 + ; test8.c:27: default: c = 99; +_L00113: + LOAD s0, 63 + STORE s0, _main_c_1_1_0 + ; test8.c:29: } +_L00115: + RETURN +;-------------------------------------------------------- +; interrupt vector +;-------------------------------------------------------- diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/expected/test8.pblazeide.psm sdcc-src-3.1.0-pblaze/device/examples/pblaze/expected/test8.pblazeide.psm --- sdcc-src-3.1.0/device/examples/pblaze/expected/test8.pblazeide.psm 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/expected/test8.pblazeide.psm 2011-08-23 15:57:26.000000000 +0200 @@ -0,0 +1,144 @@ +;-------------------------------------------------------- +; File Created by SDCC : free open source ANSI-C Compiler +; Version 3.0.1 #6227 (Feb 20 2011) (Linux) +; This file was generated Fri Apr 22 14:09:02 2011 +;-------------------------------------------------------- +;-------------------------------------------------------- +; global & static initialisations +;-------------------------------------------------------- + _main_c_1_1_0 EQU $00 + + LOAD sF, $3f + JUMP __sdcc_program_startup +;-------------------------------------------------------- +; Home +;-------------------------------------------------------- +__sdcc_program_startup: + CALL _main +; return from main will lock up +__sdcc_loop: + JUMP __sdcc_loop +;-------------------------------------------------------- +; code +;-------------------------------------------------------- +;------------------------------------------------------------ +;Allocation info for local variables in function 'main' +;------------------------------------------------------------ +;------------------------------------------------------------ +_main: + ; test8.c:3: void main() + ; test8.c:5: volatile char c = 5; + LOAD s0, $05 + STORE s0, _main_c_1_1_0 + ; test8.c:8: switch(c) + FETCH s0, _main_c_1_1_0 + COMP s0, $0a + JUMP NZ, _LC00101 + JUMP _L00101 +_LC00101: + COMP s0, $0b + JUMP NZ, _LC00102 + JUMP _L00102 +_LC00102: + COMP s0, $0c + JUMP NZ, _LC00103 + JUMP _L00103 +_LC00103: + COMP s0, $0d + JUMP NZ, _LC00104 + JUMP _L00104 +_LC00104: + COMP s0, $0e + JUMP NZ, _LC00105 + JUMP _L00105 +_LC00105: + JUMP _L00106 + ; test8.c:10: case 10: c = 11; break; +_L00101: + LOAD s0, $0b + STORE s0, _main_c_1_1_0 + JUMP _L00107 + ; test8.c:11: case 11: c = 22; break; +_L00102: + LOAD s0, $16 + STORE s0, _main_c_1_1_0 + JUMP _L00107 + ; test8.c:12: case 12: c = 33; break; +_L00103: + LOAD s0, $21 + STORE s0, _main_c_1_1_0 + JUMP _L00107 + ; test8.c:13: case 13: c = 44; break; +_L00104: + LOAD s0, $2c + STORE s0, _main_c_1_1_0 + JUMP _L00107 + ; test8.c:14: case 14: c = 55; break; +_L00105: + LOAD s0, $37 + STORE s0, _main_c_1_1_0 + JUMP _L00107 + ; test8.c:15: default: c = 99; +_L00106: + LOAD s0, $63 + STORE s0, _main_c_1_1_0 + ; test8.c:17: } +_L00107: + ; test8.c:20: switch(c) + FETCH s0, _main_c_1_1_0 + COMP s0, $04 + JUMP NZ, _LC00106 + JUMP _L00111 +_LC00106: + COMP s0, $0a + JUMP NZ, _LC00107 + JUMP _L00108 +_LC00107: + COMP s0, $17 + JUMP NZ, _LC00108 + JUMP _L00109 +_LC00108: + COMP s0, $1f + JUMP NZ, _LC00109 + JUMP _L00110 +_LC00109: + COMP s0, $3b + JUMP NZ, _LC00110 + JUMP _L00112 +_LC00110: + JUMP _L00113 + ; test8.c:22: case 10: c = 11; break; +_L00108: + LOAD s0, $0b + STORE s0, _main_c_1_1_0 + JUMP _L00115 + ; test8.c:23: case 23: c = 22; break; +_L00109: + LOAD s0, $16 + STORE s0, _main_c_1_1_0 + JUMP _L00115 + ; test8.c:24: case 31: c = 33; break; +_L00110: + LOAD s0, $21 + STORE s0, _main_c_1_1_0 + JUMP _L00115 + ; test8.c:25: case 4: c = 44; break; +_L00111: + LOAD s0, $2c + STORE s0, _main_c_1_1_0 + JUMP _L00115 + ; test8.c:26: case 59: c = 55; break; +_L00112: + LOAD s0, $37 + STORE s0, _main_c_1_1_0 + JUMP _L00115 + ; test8.c:27: default: c = 99; +_L00113: + LOAD s0, $63 + STORE s0, _main_c_1_1_0 + ; test8.c:29: } +_L00115: + RET +;-------------------------------------------------------- +; interrupt vector +;-------------------------------------------------------- diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/expected/test9.kcpsm.psm sdcc-src-3.1.0-pblaze/device/examples/pblaze/expected/test9.kcpsm.psm --- sdcc-src-3.1.0/device/examples/pblaze/expected/test9.kcpsm.psm 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/expected/test9.kcpsm.psm 2011-08-23 15:57:26.000000000 +0200 @@ -0,0 +1,125 @@ +;-------------------------------------------------------- +; File Created by SDCC : free open source ANSI-C Compiler +; Version 3.0.1 #6227 (Feb 20 2011) (Linux) +; This file was generated Fri Apr 22 14:06:01 2011 +;-------------------------------------------------------- +;-------------------------------------------------------- +; global & static initialisations +;-------------------------------------------------------- + CONSTANT _main_c_1_1_0, 00 + + LOAD sF, 3f + JUMP __sdcc_program_startup +;-------------------------------------------------------- +; Home +;-------------------------------------------------------- +__sdcc_program_startup: + CALL _main +; return from main will lock up +__sdcc_loop: + JUMP __sdcc_loop +;-------------------------------------------------------- +; code +;-------------------------------------------------------- +;------------------------------------------------------------ +;Allocation info for local variables in function 'main' +;------------------------------------------------------------ +;------------------------------------------------------------ +_main: + ; test9.c:7: void main() + ; test9.c:9: volatile char c = 1; + LOAD s0, 01 + STORE s0, _main_c_1_1_0 + ; test9.c:10: c = !c; + FETCH s0, _main_c_1_1_0 + LOAD s1, 00 + COMPARE s0, 00 + JUMP NZ, _LC00101 + LOAD s1, 01 +_LC00101: + STORE s1, _main_c_1_1_0 + ; test9.c:11: c = 0; + LOAD s0, 00 + STORE s0, _main_c_1_1_0 + ; test9.c:12: c = !c; + FETCH s0, _main_c_1_1_0 + LOAD s1, 00 + COMPARE s0, 00 + JUMP NZ, _LC00102 + LOAD s1, 01 +_LC00102: + STORE s1, _main_c_1_1_0 + ; test9.c:13: c = c && c; + FETCH s0, _main_c_1_1_0 + COMPARE s0, 00 + JUMP NZ, _LC00103 + JUMP _L00103 +_LC00103: + FETCH s0, _main_c_1_1_0 + COMPARE s0, 00 + JUMP Z, _LC00104 + JUMP _L00104 +_LC00104: +_L00103: + LOAD s0, 00 + JUMP _L00105 +_L00104: + LOAD s0, 01 +_L00105: + STORE s0, _main_c_1_1_0 + ; test9.c:14: c = c || c; + FETCH s0, _main_c_1_1_0 + COMPARE s0, 00 + JUMP Z, _LC00105 + JUMP _L00107 +_LC00105: + FETCH s0, _main_c_1_1_0 + COMPARE s0, 00 + JUMP Z, _LC00106 + JUMP _L00107 +_LC00106: + LOAD s0, 00 + JUMP _L00108 +_L00107: + LOAD s0, 01 +_L00108: + STORE s0, _main_c_1_1_0 + ; test9.c:15: c = 29; + LOAD s0, 1d + STORE s0, _main_c_1_1_0 + ; test9.c:16: c = c % 13; + FETCH s0, _main_c_1_1_0 + LOAD sB, s0 + LOAD sC, 0d + CALL __moduschar + LOAD s0, sB + STORE s0, _main_c_1_1_0 +_L00101: + RETURN + +__moduchar: +__moduschar: + CALL __divuschar + XOR sB, sC + XOR sC, sB + XOR sB, sC + RETURN + +__divuchar: + LOAD sE, 08 + LOAD sD, sC + LOAD sC, 00 +_L00107: + SL0 sB + SLA sC + COMPARE sC, sD + JUMP C, _L00108 + SUB sC, sD + ADD sB, 01 +_L00108: + SUB sE, 01 + JUMP NZ, _L00107 + RETURN +;-------------------------------------------------------- +; interrupt vector +;-------------------------------------------------------- diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/expected/test9.pblazeide.psm sdcc-src-3.1.0-pblaze/device/examples/pblaze/expected/test9.pblazeide.psm --- sdcc-src-3.1.0/device/examples/pblaze/expected/test9.pblazeide.psm 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/expected/test9.pblazeide.psm 2011-08-23 15:57:26.000000000 +0200 @@ -0,0 +1,125 @@ +;-------------------------------------------------------- +; File Created by SDCC : free open source ANSI-C Compiler +; Version 3.0.1 #6227 (Feb 20 2011) (Linux) +; This file was generated Fri Apr 22 14:08:58 2011 +;-------------------------------------------------------- +;-------------------------------------------------------- +; global & static initialisations +;-------------------------------------------------------- + _main_c_1_1_0 EQU $00 + + LOAD sF, $3f + JUMP __sdcc_program_startup +;-------------------------------------------------------- +; Home +;-------------------------------------------------------- +__sdcc_program_startup: + CALL _main +; return from main will lock up +__sdcc_loop: + JUMP __sdcc_loop +;-------------------------------------------------------- +; code +;-------------------------------------------------------- +;------------------------------------------------------------ +;Allocation info for local variables in function 'main' +;------------------------------------------------------------ +;------------------------------------------------------------ +_main: + ; test9.c:7: void main() + ; test9.c:9: volatile char c = 1; + LOAD s0, $01 + STORE s0, _main_c_1_1_0 + ; test9.c:10: c = !c; + FETCH s0, _main_c_1_1_0 + LOAD s1, $00 + COMP s0, $00 + JUMP NZ, _LC00101 + LOAD s1, $01 +_LC00101: + STORE s1, _main_c_1_1_0 + ; test9.c:11: c = 0; + LOAD s0, $00 + STORE s0, _main_c_1_1_0 + ; test9.c:12: c = !c; + FETCH s0, _main_c_1_1_0 + LOAD s1, $00 + COMP s0, $00 + JUMP NZ, _LC00102 + LOAD s1, $01 +_LC00102: + STORE s1, _main_c_1_1_0 + ; test9.c:13: c = c && c; + FETCH s0, _main_c_1_1_0 + COMP s0, $00 + JUMP NZ, _LC00103 + JUMP _L00103 +_LC00103: + FETCH s0, _main_c_1_1_0 + COMP s0, $00 + JUMP Z, _LC00104 + JUMP _L00104 +_LC00104: +_L00103: + LOAD s0, $00 + JUMP _L00105 +_L00104: + LOAD s0, $01 +_L00105: + STORE s0, _main_c_1_1_0 + ; test9.c:14: c = c || c; + FETCH s0, _main_c_1_1_0 + COMP s0, $00 + JUMP Z, _LC00105 + JUMP _L00107 +_LC00105: + FETCH s0, _main_c_1_1_0 + COMP s0, $00 + JUMP Z, _LC00106 + JUMP _L00107 +_LC00106: + LOAD s0, $00 + JUMP _L00108 +_L00107: + LOAD s0, $01 +_L00108: + STORE s0, _main_c_1_1_0 + ; test9.c:15: c = 29; + LOAD s0, $1d + STORE s0, _main_c_1_1_0 + ; test9.c:16: c = c % 13; + FETCH s0, _main_c_1_1_0 + LOAD sB, s0 + LOAD sC, $0d + CALL __moduschar + LOAD s0, sB + STORE s0, _main_c_1_1_0 +_L00101: + RET + +__moduchar: +__moduschar: + CALL __divuschar + XOR sB, sC + XOR sC, sB + XOR sB, sC + RET + +__divuchar: + LOAD sE, $08 + LOAD sD, sC + LOAD sC, $00 +_L00107: + SL0 sB + SLA sC + COMP sC, sD + JUMP C, _L00108 + SUB sC, sD + ADD sB, $01 +_L00108: + SUB sE, $01 + JUMP NZ, _L00107 + RET +;-------------------------------------------------------- +; interrupt vector +;-------------------------------------------------------- diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/expected/testM2.kcpsm.psm sdcc-src-3.1.0-pblaze/device/examples/pblaze/expected/testM2.kcpsm.psm --- sdcc-src-3.1.0/device/examples/pblaze/expected/testM2.kcpsm.psm 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/expected/testM2.kcpsm.psm 2011-08-23 15:57:26.000000000 +0200 @@ -0,0 +1,230 @@ +;-------------------------------------------------------- +; File Created by SDCC : free open source ANSI-C Compiler +; Version 3.0.1 #6227 (Feb 20 2011) (Linux) +; This file was generated Fri Apr 22 14:32:23 2011 +;-------------------------------------------------------- +;-------------------------------------------------------- +; global & static initialisations +;-------------------------------------------------------- + CONSTANT _fun_val_1_1_0, 00 + CONSTANT _pole_7, 01 + CONSTANT _pole_6, 02 + CONSTANT _pole_5, 03 + CONSTANT _pole_4, 04 + CONSTANT _pole_3, 05 + CONSTANT _pole_2, 06 + CONSTANT _pole_1, 07 + CONSTANT _pole_0, 08 + CONSTANT _text_4, 09 + CONSTANT _text_3, 0a + CONSTANT _text_2, 0b + CONSTANT _text_1, 0c + CONSTANT _text_0, 0d + CONSTANT _nepole_1, 0e + CONSTANT _nepole_0, 0f + CONSTANT _main_a_1_1_0, 10 + CONSTANT _main_b_1_1_0, 11 + +;------------------------------------------------------------ +;Allocation info for local variables in function 'main' +;------------------------------------------------------------ +;------------------------------------------------------------ + ; testM2.c:3: int pole[] = {100,200,300,400}; + LOAD s0, _pole_7 + LOAD s1, 00 + STORE s1, (s0) + ADD s0, 01 + LOAD s1, 64 + STORE s1, (s0) + SUB s0, 01 + LOAD s1, s0 + ADD s1, 02 + LOAD s2, 00 + STORE s2, (s1) + ADD s1, 01 + LOAD s2, c8 + STORE s2, (s1) + ADD s1, 01 + LOAD s2, 01 + STORE s2, (s1) + ADD s1, 01 + LOAD s2, 2c + STORE s2, (s1) + ADD s1, 01 + LOAD s0, 01 + STORE s0, (s1) + ADD s1, 01 + LOAD s0, 90 + STORE s0, (s1) + LOAD sF, 3f + JUMP __sdcc_program_startup +;-------------------------------------------------------- +; Home +;-------------------------------------------------------- +__sdcc_program_startup: + CALL _main +; return from main will lock up +__sdcc_loop: + JUMP __sdcc_loop +;-------------------------------------------------------- +; code +;-------------------------------------------------------- +;------------------------------------------------------------ +;Allocation info for local variables in function 'main' +;------------------------------------------------------------ +;------------------------------------------------------------ + ; testM2.c:10: char fun( volatile char *a, int b, char c, char *d) +_fun: + LOAD s0, sC + LOAD s1, sD + LOAD s2, sE + ; testM2.c:12: volatile char val = 0; + LOAD s3, 00 + STORE s3, _fun_val_1_1_0 + ; testM2.c:13: char t1 = *d; + ADD sF, 01 + FETCH s3, (sF) + FETCH s4, (s3) + ; testM2.c:15: val = val * c; + FETCH s5, _fun_val_1_1_0 + LOAD sB, s5 + LOAD sC, s2 + CALL __mulschar + LOAD s2, sB + STORE s2, _fun_val_1_1_0 + ; testM2.c:16: b = pole[3] & pole[1]; + LOAD s2, _pole_7 + LOAD s5, s2 + ADD s5, 06 + FETCH s6, (s5) + ADD s5, 01 + FETCH s7, (s5) + ADD s2, 02 + FETCH s5, (s2) + ADD s2, 01 + FETCH s8, (s2) + AND s7, s8 + AND s6, s5 + ; testM2.c:17: text[2] = 'R'; + LOAD s0, _text_4 + LOAD s1, s0 + ADD s1, 02 + LOAD s2, 52 + STORE s2, (s1) + ; testM2.c:18: *d = text[3]; + ADD s0, 03 + FETCH s1, (s0) + STORE s1, (s3) + ; testM2.c:19: return t1 + b + nepole; + ADD s4, s7 + FETCH s1, _nepole_0 + LOAD s0, s1 + ADD s4, s0 + LOAD sB, s4 +_L00101: + RETURN +;------------------------------------------------------------ +;Allocation info for local variables in function 'main' +;------------------------------------------------------------ +;------------------------------------------------------------ +_main: + ; testM2.c:22: void main() + ; testM2.c:24: volatile char a = 10; + LOAD s0, 0a + STORE s0, _main_a_1_1_0 + ; testM2.c:25: volatile char b = 20; + LOAD s0, 14 + STORE s0, _main_b_1_1_0 + ; testM2.c:26: char c = 30; + LOAD s0, 1e + STORE s0, 14 + ; testM2.c:27: gptr = &nepole; + LOAD s0, _nepole_1 + LOAD s1, s0 + ; testM2.c:28: vgptr = &nepole; + ; testM2.c:29: pole[1] = 150; + LOAD s2, _pole_7 + LOAD s3, s2 + ADD s3, 02 + LOAD s4, 00 + STORE s4, (s3) + ADD s3, 01 + LOAD s4, 96 + STORE s4, (s3) + ; testM2.c:30: pole[0] = *gptr; + FETCH s3, (s1) + ADD s1, 01 + FETCH s4, (s1) + STORE s3, (s2) + ADD s2, 01 + STORE s4, (s2) + ; testM2.c:31: *vgptr = 18; + LOAD s1, 00 + STORE s1, (s0) + ADD s0, 01 + LOAD s1, 12 + STORE s1, (s0) + ; testM2.c:32: fun(&a,555,c, &c); + LOAD s0, 14 + FETCH s2, 14 + LOAD s1, s2 + LOAD s2, _main_a_1_1_0 + STORE s0, (sF) + SUB sF, 01 + LOAD sB, s2 + LOAD sC, 2b + LOAD sD, 02 + LOAD sE, s1 + CALL _fun + ; testM2.c:33: nepole = c; + FETCH s1, 14 + LOAD s0, s1 + LOAD s1, 00 + TEST s0, 80 + SUBCY s1, 00 +_L00101: + STORE s1, _nepole_1 + STORE s0, _nepole_0 + RETURN + +__mulschar: + LOAD sA, 00 + TEST sB, 80 + JUMP Z, _L00104 + XOR sB, FF + ADD sB, 01 + LOAD sA, 01 +_L00104: + TEST sC, 80 + JUMP Z, _L00105 + XOR sC, FF + ADD sC, 01 + XOR sA, 01 +_L00105: + CALL __muluchar + TEST sA, 01 + JUMP Z, _L00106 + XOR sB, FF + XOR sC, FF + ADD sB, 01 + ADDCY sC, 00 +_L00106: + RETURN + +__muluchar: + LOAD sE, 08 + LOAD sD, sC + LOAD sC, 00 +_L00108: + TEST sB, 01 + JUMP Z, _L00107 + ADD sC, sD +_L00107: + SR0 sC + SRA sB + SUB sE, 01 + JUMP NZ, _L00108 + RETURN +;-------------------------------------------------------- +; interrupt vector +;-------------------------------------------------------- diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/expected/testM2.pblazeide.psm sdcc-src-3.1.0-pblaze/device/examples/pblaze/expected/testM2.pblazeide.psm --- sdcc-src-3.1.0/device/examples/pblaze/expected/testM2.pblazeide.psm 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/expected/testM2.pblazeide.psm 2011-08-23 15:57:26.000000000 +0200 @@ -0,0 +1,230 @@ +;-------------------------------------------------------- +; File Created by SDCC : free open source ANSI-C Compiler +; Version 3.0.1 #6227 (Feb 20 2011) (Linux) +; This file was generated Fri Apr 22 14:10:03 2011 +;-------------------------------------------------------- +;-------------------------------------------------------- +; global & static initialisations +;-------------------------------------------------------- + _fun_val_1_1_0 EQU $00 + _pole_7 EQU $01 + _pole_6 EQU $02 + _pole_5 EQU $03 + _pole_4 EQU $04 + _pole_3 EQU $05 + _pole_2 EQU $06 + _pole_1 EQU $07 + _pole_0 EQU $08 + _text_4 EQU $09 + _text_3 EQU $0a + _text_2 EQU $0b + _text_1 EQU $0c + _text_0 EQU $0d + _nepole_1 EQU $0e + _nepole_0 EQU $0f + _main_a_1_1_0 EQU $10 + _main_b_1_1_0 EQU $11 + +;------------------------------------------------------------ +;Allocation info for local variables in function 'main' +;------------------------------------------------------------ +;------------------------------------------------------------ + ; testM2.c:3: int pole[] = {100,200,300,400}; + LOAD s0, _pole_7 + LOAD s1, $00 + STORE s1, (s0) + ADD s0, $01 + LOAD s1, $64 + STORE s1, (s0) + SUB s0, $01 + LOAD s1, s0 + ADD s1, $02 + LOAD s2, $00 + STORE s2, (s1) + ADD s1, $01 + LOAD s2, $c8 + STORE s2, (s1) + ADD s1, $01 + LOAD s2, $01 + STORE s2, (s1) + ADD s1, $01 + LOAD s2, $2c + STORE s2, (s1) + ADD s1, $01 + LOAD s0, $01 + STORE s0, (s1) + ADD s1, $01 + LOAD s0, $90 + STORE s0, (s1) + LOAD sF, $3f + JUMP __sdcc_program_startup +;-------------------------------------------------------- +; Home +;-------------------------------------------------------- +__sdcc_program_startup: + CALL _main +; return from main will lock up +__sdcc_loop: + JUMP __sdcc_loop +;-------------------------------------------------------- +; code +;-------------------------------------------------------- +;------------------------------------------------------------ +;Allocation info for local variables in function 'main' +;------------------------------------------------------------ +;------------------------------------------------------------ + ; testM2.c:10: char fun( volatile char *a, int b, char c, char *d) +_fun: + LOAD s0, sC + LOAD s1, sD + LOAD s2, sE + ; testM2.c:12: volatile char val = 0; + LOAD s3, $00 + STORE s3, _fun_val_1_1_0 + ; testM2.c:13: char t1 = *d; + ADD sF, $01 + FETCH s3, (sF) + FETCH s4, (s3) + ; testM2.c:15: val = val * c; + FETCH s5, _fun_val_1_1_0 + LOAD sB, s5 + LOAD sC, s2 + CALL __mulschar + LOAD s2, sB + STORE s2, _fun_val_1_1_0 + ; testM2.c:16: b = pole[3] & pole[1]; + LOAD s2, _pole_7 + LOAD s5, s2 + ADD s5, $06 + FETCH s6, (s5) + ADD s5, $01 + FETCH s7, (s5) + ADD s2, $02 + FETCH s5, (s2) + ADD s2, $01 + FETCH s8, (s2) + AND s7, s8 + AND s6, s5 + ; testM2.c:17: text[2] = 'R'; + LOAD s0, _text_4 + LOAD s1, s0 + ADD s1, $02 + LOAD s2, $52 + STORE s2, (s1) + ; testM2.c:18: *d = text[3]; + ADD s0, $03 + FETCH s1, (s0) + STORE s1, (s3) + ; testM2.c:19: return t1 + b + nepole; + ADD s4, s7 + FETCH s1, _nepole_0 + LOAD s0, s1 + ADD s4, s0 + LOAD sB, s4 +_L00101: + RET +;------------------------------------------------------------ +;Allocation info for local variables in function 'main' +;------------------------------------------------------------ +;------------------------------------------------------------ +_main: + ; testM2.c:22: void main() + ; testM2.c:24: volatile char a = 10; + LOAD s0, $0a + STORE s0, _main_a_1_1_0 + ; testM2.c:25: volatile char b = 20; + LOAD s0, $14 + STORE s0, _main_b_1_1_0 + ; testM2.c:26: char c = 30; + LOAD s0, $1e + STORE s0, 14 + ; testM2.c:27: gptr = &nepole; + LOAD s0, _nepole_1 + LOAD s1, s0 + ; testM2.c:28: vgptr = &nepole; + ; testM2.c:29: pole[1] = 150; + LOAD s2, _pole_7 + LOAD s3, s2 + ADD s3, $02 + LOAD s4, $00 + STORE s4, (s3) + ADD s3, $01 + LOAD s4, $96 + STORE s4, (s3) + ; testM2.c:30: pole[0] = *gptr; + FETCH s3, (s1) + ADD s1, $01 + FETCH s4, (s1) + STORE s3, (s2) + ADD s2, $01 + STORE s4, (s2) + ; testM2.c:31: *vgptr = 18; + LOAD s1, $00 + STORE s1, (s0) + ADD s0, $01 + LOAD s1, $12 + STORE s1, (s0) + ; testM2.c:32: fun(&a,555,c, &c); + LOAD s0, 14 + FETCH s2, 14 + LOAD s1, s2 + LOAD s2, _main_a_1_1_0 + STORE s0, (sF) + SUB sF, $01 + LOAD sB, s2 + LOAD sC, $2b + LOAD sD, $02 + LOAD sE, s1 + CALL _fun + ; testM2.c:33: nepole = c; + FETCH s1, 14 + LOAD s0, s1 + LOAD s1, $00 + TEST s0, $80 + SUBC s1, $00 +_L00101: + STORE s1, _nepole_1 + STORE s0, _nepole_0 + RET + +__mulschar: + LOAD sA, $00 + TEST sB, $80 + JUMP Z, _L00104 + XOR sB, $FF + ADD sB, $01 + LOAD sA, $01 +_L00104: + TEST sC, $80 + JUMP Z, _L00105 + XOR sC, $FF + ADD sC, $01 + XOR sA, $01 +_L00105: + CALL __muluchar + TEST sA, $01 + JUMP Z, _L00106 + XOR sB, $FF + XOR sC, $FF + ADD sB, $01 + ADDC sC, $00 +_L00106: + RET + +__muluchar: + LOAD sE, $08 + LOAD sD, sC + LOAD sC, $00 +_L00108: + TEST sB, $01 + JUMP Z, _L00107 + ADD sC, sD +_L00107: + SR0 sC + SRA sB + SUB sE, $01 + JUMP NZ, _L00108 + RET +;-------------------------------------------------------- +; interrupt vector +;-------------------------------------------------------- diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/funargs.c sdcc-src-3.1.0-pblaze/device/examples/pblaze/funargs.c --- sdcc-src-3.1.0/device/examples/pblaze/funargs.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/funargs.c 2011-08-23 15:57:24.000000000 +0200 @@ -0,0 +1,15 @@ +char f(char arg, char arg2) +{ + return arg+arg2; +} + + +void main() +{ + char i = 0; + for(; i < 10; i++) + { + i++; + f(i, 17); + } +} diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/funlit.c sdcc-src-3.1.0-pblaze/device/examples/pblaze/funlit.c --- sdcc-src-3.1.0/device/examples/pblaze/funlit.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/funlit.c 2011-08-23 15:57:24.000000000 +0200 @@ -0,0 +1,14 @@ +char sum(char nnn1, char n2, char n3) +{ + return nnn1 + n2 + n3; +} + + +void main() +{ + char c = 29; + char d = 57; + char e = 113; + sum (c, d, e); + +} \ No newline at end of file diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/funstruct.c sdcc-src-3.1.0-pblaze/device/examples/pblaze/funstruct.c --- sdcc-src-3.1.0/device/examples/pblaze/funstruct.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/funstruct.c 2011-08-23 15:57:26.000000000 +0200 @@ -0,0 +1,31 @@ +struct s { + int a; + char b; +} struktura; + +int sum(char nnn1, short n2, int n3) +{ + return (int)nnn1 + n2 + n3; +} + +void main() +{ + char c = 29; + short d = 57; + int e = 113; + + + if (sum(1, 2, 3) > 5) + { + sum(2, 3, c + d); + return; + } + else + { + struktura.a = 99; + } + struktura.a = 2*e; + struktura.b = c; + sum (struktura.b, d, e); + +} \ No newline at end of file diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/funvar.c sdcc-src-3.1.0-pblaze/device/examples/pblaze/funvar.c --- sdcc-src-3.1.0/device/examples/pblaze/funvar.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/funvar.c 2011-08-23 15:57:24.000000000 +0200 @@ -0,0 +1,11 @@ +char globvar = 13; + +char test(char x) +{ + return x; +} + +void main() +{ + test(globvar); +} \ No newline at end of file diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/intr.c sdcc-src-3.1.0-pblaze/device/examples/pblaze/intr.c --- sdcc-src-3.1.0/device/examples/pblaze/intr.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/intr.c 2011-08-23 15:57:24.000000000 +0200 @@ -0,0 +1,18 @@ +// test of inserted asm code into C code +int i; + +void ihandler() __interrupt (3) __using (7) +{ + _asm + DISALBE INTERRUPT + _endasm; +} + +int main(int x, int y) +{ +_asm +INPUT s0 +_endasm; +i = 10; +return i; +} \ No newline at end of file diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/lcd.c sdcc-src-3.1.0-pblaze/device/examples/pblaze/lcd.c --- sdcc-src-3.1.0/device/examples/pblaze/lcd.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/lcd.c 2011-08-23 15:57:24.000000000 +0200 @@ -0,0 +1,54 @@ +//#include <stdio.h> + +void __port_write(char port, char arg) { } +char __port_read(char port) { } +void __nop() { } + +#define LED_wr(arg) __port_write(0x80, (arg)) + +#define LCD_wr(arg) __port_write(0x01, (arg)) +#define LCD_rd() __port_read(0x01) +#define LCD_busy() (LCD_rd() & 0x80) == 0x80 + +void delay_ms(int ms) +{ + int i; + for (i=0;i<ms;i++) { + for (i=0; i < 10000; i++) __nop(); + } +} + +void LCD_init() +{ + LCD_wr(0x42); + while (LCD_rd()) { __nop();} + LCD_wr(0x43); + delay_ms(10); + LCD_wr(0x44); + LCD_wr(0x45); +} + +void LCD_write(char ch) +{ + LCD_wr(0x46); + LCD_wr(0x47); +} + + +int main(void) { + char st = 0; + + while(1) { + LED_wr(st); + st ^= 1; + delay_ms(1000); + } +/* + char ch = 0x31; + LCD_init(); + while (1) { + LCD_write(ch); + delay_ms(1000); + } +*/ +} diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/operators.c sdcc-src-3.1.0-pblaze/device/examples/pblaze/operators.c --- sdcc-src-3.1.0/device/examples/pblaze/operators.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/operators.c 2011-08-23 15:57:24.000000000 +0200 @@ -0,0 +1,11 @@ +int main() +{ + int i = 0; + int j = 13; +zkouska: + i += 2; + j -= i; + i |= j; + goto zkouska; + return i*j; +} \ No newline at end of file diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/pointers.c sdcc-src-3.1.0-pblaze/device/examples/pblaze/pointers.c --- sdcc-src-3.1.0/device/examples/pblaze/pointers.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/pointers.c 2011-08-23 15:57:24.000000000 +0200 @@ -0,0 +1 @@ +// TODO \ No newline at end of file diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/simplefunc.c sdcc-src-3.1.0-pblaze/device/examples/pblaze/simplefunc.c --- sdcc-src-3.1.0/device/examples/pblaze/simplefunc.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/simplefunc.c 2011-08-23 15:57:24.000000000 +0200 @@ -0,0 +1,12 @@ +char inc(char number) +{ + return number + 1; +} + + +void main() +{ + char c = 42; + inc(c); + +} \ No newline at end of file diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/stubs.c sdcc-src-3.1.0-pblaze/device/examples/pblaze/stubs.c --- sdcc-src-3.1.0/device/examples/pblaze/stubs.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/stubs.c 2011-08-23 15:57:24.000000000 +0200 @@ -0,0 +1,5 @@ +void main() +{ +int i = 42; +for (;;) {i--;}; +} \ No newline at end of file diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/test10.c sdcc-src-3.1.0-pblaze/device/examples/pblaze/test10.c --- sdcc-src-3.1.0/device/examples/pblaze/test10.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/test10.c 2011-08-23 15:57:24.000000000 +0200 @@ -0,0 +1,23 @@ +// test array of ints + +#define ARRAY_SIZE 10 + +volatile short numbers[ARRAY_SIZE] = {9,8,7,6,5,4,3,2,1,0}; + +void main() +{ + short i, j, temp; + + for (i = (ARRAY_SIZE - 1); i > 0; i--) + { + for (j = 1; j <= i; j++) + { + if (numbers[j-1] > numbers[j]) + { + temp = numbers[j-1]; + numbers[j-1] = numbers[j]; + numbers[j] = temp; + } + } + } +} diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/test6.c sdcc-src-3.1.0-pblaze/device/examples/pblaze/test6.c --- sdcc-src-3.1.0/device/examples/pblaze/test6.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/test6.c 2011-08-23 15:57:24.000000000 +0200 @@ -0,0 +1,22 @@ +// interrupt handler test for pBlazeIDE + +char __xdata val = 0; +char __xdata c; + +void interruptHandler() __interrupt +{ + val++; +} + +void main() +{ + c = 0; + __asm + EINT + __endasm; + + for (;;) { + + c += 4; + } +} diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/test7.c sdcc-src-3.1.0-pblaze/device/examples/pblaze/test7.c --- sdcc-src-3.1.0/device/examples/pblaze/test7.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/test7.c 2011-08-23 15:57:24.000000000 +0200 @@ -0,0 +1,30 @@ +// test bitových operacà vÅ¡eho druhu (pBlazeIDE) + +void main() +{ + volatile unsigned char c = 1; + volatile unsigned char d = 1; + volatile unsigned char e = 15; + + c <<= 4; + + c >>= 3; + + c |= c; + + c |= d + 1; + + c = c & d; + + d = ~e; + + e = c ^ d; + + c = !c && d || e; + c = c || e; + + if (!c) + { + c = -e; + } +} diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/test8.c sdcc-src-3.1.0-pblaze/device/examples/pblaze/test8.c --- sdcc-src-3.1.0/device/examples/pblaze/test8.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/test8.c 2011-08-23 15:57:24.000000000 +0200 @@ -0,0 +1,31 @@ +// switch test + +void main() +{ + volatile char c = 5; + + // JUMPTABLE generated + switch(c) + { + case 10: c = 11; break; + case 11: c = 22; break; + case 12: c = 33; break; + case 13: c = 44; break; + case 14: c = 55; break; + default: c = 99; + break; + } + + // sequence of IFXs generated + switch(c) + { + case 10: c = 11; break; + case 23: c = 22; break; + case 31: c = 33; break; + case 4: c = 44; break; + case 59: c = 55; break; + default: c = 99; + break; + } + +} diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/test9.c sdcc-src-3.1.0-pblaze/device/examples/pblaze/test9.c --- sdcc-src-3.1.0/device/examples/pblaze/test9.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/test9.c 2011-08-23 15:57:24.000000000 +0200 @@ -0,0 +1,17 @@ +// test bitových operacà - problem with NOT_OP (pBlazeIDE) + +/* link the C libarary */ + +//#pragma library c + +void main() +{ + volatile char c = 1; + c = !c; + c = 0; + c = !c; + c = c && c; + c = c || c; + c = 29; + c = c % 13; +} diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/testINOUT.c sdcc-src-3.1.0-pblaze/device/examples/pblaze/testINOUT.c --- sdcc-src-3.1.0/device/examples/pblaze/testINOUT.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/testINOUT.c 2011-08-23 15:57:24.000000000 +0200 @@ -0,0 +1,20 @@ +// test INPUT/OUTPUT instrukci +volatile char gl = 5; + +// definice portu +extern char PBLAZEPORT[]; + +void fun(char *a) +{ + char i; + for(i = 0; i < *a; i++) { + PBLAZEPORT[i] = gl; + } +} + +void main() +{ + char a = PBLAZEPORT[5]; + fun(&a); + +} diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/testM2.c sdcc-src-3.1.0-pblaze/device/examples/pblaze/testM2.c --- sdcc-src-3.1.0/device/examples/pblaze/testM2.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/testM2.c 2011-08-23 15:57:24.000000000 +0200 @@ -0,0 +1,35 @@ +// test ruzne typy ukazatelu + +int pole[] = {100,200,300,400}; +char text[] = "Pepa"; +int nepole = 6; +volatile int *vgptr; +int *gptr; + + +char fun( volatile char *a, int b, char c, char *d) +{ + volatile char val = 0; + char t1 = *d; + + val = val * c; + b = pole[3] & pole[1]; + text[2] = 'R'; + *d = text[3]; + return t1 + b + nepole; +} + +void main() +{ + volatile char a = 10; + volatile char b = 20; + char c = 30; + gptr = &nepole; + vgptr = &nepole; + pole[1] = 150; + pole[0] = *gptr; + *vgptr = 18; + fun(&a,555,c, &c); + nepole = c; + +} diff -NaurbB sdcc-src-3.1.0/device/examples/pblaze/types.c sdcc-src-3.1.0-pblaze/device/examples/pblaze/types.c --- sdcc-src-3.1.0/device/examples/pblaze/types.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/examples/pblaze/types.c 2011-08-23 15:57:24.000000000 +0200 @@ -0,0 +1,18 @@ +int i; +struct stype { + int x; + int y; +} str; + +int f(char a, short b) +{ + return a + b; +} + + +int main(void) +{ +// stype lstr; + i = str.x = str.y = 13; + return f(i, str.x); +} \ No newline at end of file diff -NaurbB sdcc-src-3.1.0/device/include/Makefile.in sdcc-src-3.1.0-pblaze/device/include/Makefile.in --- sdcc-src-3.1.0/device/include/Makefile.in 2011-10-12 16:09:15.000000000 +0200 +++ sdcc-src-3.1.0-pblaze/device/include/Makefile.in 2011-12-05 22:46:57.573665600 +0100 @@ -71,6 +71,10 @@ done; \ done; \ fi + # picoblaze + if [ "`grep pblaze $(top_builddir)/ports.build`" = pblaze ]; then \ + $(CP) $(srcdir)/pblaze/*.h $(sdcc_includedir)/pblaze; \ + fi find $(sdcc_includedir) -type d -name '.svn' -exec rm -rf {} \; # correct file modes find $(sdcc_includedir) -type f -exec chmod 644 {} \; @@ -96,7 +100,7 @@ # --------------------------------- installdirs: mkdir -p $(sdcc_includedir) - for target in mcs51 ds390 ds400 pic14 pic16 z80 z180 gbz80 hc08; \ + for target in mcs51 ds390 ds400 pic14 pic16 z80 z180 gbz80 hc08 pblaze; \ do \ if [ -d $(srcdir)/$${target} ]; \ then \ diff -NaurbB sdcc-src-3.1.0/device/include/pblaze/ctype.h sdcc-src-3.1.0-pblaze/device/include/pblaze/ctype.h --- sdcc-src-3.1.0/device/include/pblaze/ctype.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/include/pblaze/ctype.h 2011-08-23 15:56:36.000000000 +0200 @@ -0,0 +1,74 @@ +/*------------------------------------------------------------------------- + ctype.h - ANSI functions forward declarations + + Modified for pic16 port by Vangelis Rokas, 2004, vrokas@otenet.gr + + Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998) + + Revisions: + 1.0 - June.1.2000 1.0 - Bela Torok / bela.torok@kssg.ch + order: function definitions -> macros + corretced macro: isalpha(c) + added macros: _tolower(c), _toupper(c), tolower(c), toupper(c) toascii(c) + + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ + +/* +** $Id: ctype.h 3648 2005-01-22 18:02:16Z vrokas $ +*/ + + +#ifndef __CTYPE_H +#define __CTYPE_H 1 + +/* link the C libarary */ +#pragma library c + +#include <sdcc-lib.h> + +extern char iscntrl (unsigned char ) ; +extern char isdigit (unsigned char ) ; +extern char isgraph (unsigned char ) ; +extern char islower (unsigned char ) ; +extern char isupper (unsigned char ) ; +extern char isprint (unsigned char ) ; +extern char ispunct (unsigned char ) ; +extern char isspace (unsigned char ) ; +extern char isxdigit (unsigned char ) ; + +#define isalnum(c) (isalpha(c) || isdigit(c)) +#define isalpha(c) (isupper(c) || islower(c)) + +/* ANSI versions of _tolower & _toupper +#define _tolower(c) ((c) - ('a' - 'A')) +#define _toupper(c) ((c) + ('a' - 'A')) +*/ + +// The _tolower & _toupper functions below can applied to any +// alpha characters regardless of the case (upper or lower) +#define _tolower(c) ((c) | ('a' - 'A')) +#define _toupper(c) ((c) & ~('a' - 'A')) + +#define tolower(c) ((isupper(c)) ? _tolower(c) : (c)) +#define toupper(c) ((islower(c)) ? _toupper(c) : (c)) +#define toascii(c) ((c) & 0x7F) + +#endif diff -NaurbB sdcc-src-3.1.0/device/include/pblaze/delay.h sdcc-src-3.1.0-pblaze/device/include/pblaze/delay.h --- sdcc-src-3.1.0/device/include/pblaze/delay.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/include/pblaze/delay.h 2011-08-23 15:56:36.000000000 +0200 @@ -0,0 +1,75 @@ + +/* + * delay.h - delay functions header file + * + * adopted for SDCC and picoBlaze port by Zbynek Krivka, 2010 <krivka @ fit.vutbr.cz> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __DELAY_H__ +#define __DELAY_H__ + + +//#pragma library c + +/* + * the delayNNtcy family of functions performs a + * delay of NN cycles. Possible values for NN are: + * 10 10*n cycles delay + * 100 100*n cycles delay + * 1k 1000*n cycles delay + * 10k 10000*n cycles delay + * 100k 100000*n cycles delay + * 1m 1000000*n cycles delay + */ + +/* +void delay10tcy(unsigned char) __wparam; +void delay100tcy(unsigned char) __wparam; +void delay1ktcy(unsigned char) __wparam; +void delay10ktcy(unsigned char) __wparam; +void delay100ktcy(unsigned char) __wparam; +void delay1mtcy(unsigned char) __wparam; +*/ + +void delay(unsigned char time); +//TODO: void delay(unsigned int time); + +void delay(unsigned char time) +{ + volatile unsigned char i = time; + for(; i > 0; i--) + { + __asm + LOAD s2, 00 + ADD s2, 01 + + LOAD s1, 00 +rpt22: + ADD s1, 01 + + LOAD s0, 00 +rpt11: + ADD s0, 01 + JUMP NZ, rpt11 + + COMPARE s1, 00 + JUMP NZ, rpt22 + + __endasm; + } +} +#endif diff -NaurbB sdcc-src-3.1.0/device/include/pblaze/intr.h sdcc-src-3.1.0-pblaze/device/include/pblaze/intr.h --- sdcc-src-3.1.0/device/include/pblaze/intr.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/include/pblaze/intr.h 2011-08-23 15:56:36.000000000 +0200 @@ -0,0 +1,59 @@ +/* + * intr.h - Interrupts functions header file for FITKit + * + * adopted for SDCC and picoBlaze port by Zbynek Krivka, 2010 <krivka @ fit.vutbr.cz> + * +*/ + +#ifndef __INTR_H__ +#define __INTR_H__ + +#define KCPSM + +#ifdef KCPSM +#define EINT ENABLE INTERRUPT +#define DINT DISABLE INTERRUPT +#else +#define EINT EINT +#define DINT DINT +#endif + +#define BOOL unsigned char + +void pbcc_enable_interrupt(void); +void pbcc_disable_interrupt(void); +//inline bool pbcc_enabled_interrupt(); +//void pbcc_set_interrupt_handler(void *(void)) +//void pbcc_set_interrupt(BOOL enable); + + +void pbcc_enable_interrupt(void) +{ + __asm + EINT + __endasm; +} + +void pbcc_disable_interrupt(void) +{ + __asm; + DINT + __endasm; +} +/* +void pbcc_set_interrupt(BOOL enable) +{ + if (enable) + { + pbcc_enable_interrupt(); + } + else + { + pbcc_disable_interrupt(); + } + +} +*/ +#endif + + diff -NaurbB sdcc-src-3.1.0/device/include/pblaze/kbd.h sdcc-src-3.1.0-pblaze/device/include/pblaze/kbd.h --- sdcc-src-3.1.0/device/include/pblaze/kbd.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/include/pblaze/kbd.h 2011-08-23 15:56:36.000000000 +0200 @@ -0,0 +1,169 @@ +/* + * kbd.h - Keyboarch (16 keys) peripheral functions header file for FITKit + * + * adopted for SDCC and picoBlaze port by Zbynek Krivka, 2010 <krivka @ fit.vutbr.cz> + * +*/ + +#ifndef __KBD_H__ +#define __KBD_H__ + +#include "delay.h" +#include "port.h" + +#define port_kb_low 60 +#define port_kb_high 61 + +#define CHAR_SPACE 0x20 +#define CHAR_0 0x30 +#define CHAR_1 0x31 +#define CHAR_2 0x32 +#define CHAR_3 0x33 +#define CHAR_4 0x34 +#define CHAR_5 0x35 +#define CHAR_6 0x36 +#define CHAR_7 0x37 +#define CHAR_8 0x38 +#define CHAR_9 0x39 +#define CHAR_A 0x41 +#define CHAR_B 0x42 +#define CHAR_C 0x43 +#define CHAR_D 0x44 +#define CHAR_STAR 0x2A +#define CHAR_HASH 0x23 + +#define ASM_CHAR_SPACE 20 +#define ASM_CHAR_0 30 +#define ASM_CHAR_1 31 +#define ASM_CHAR_2 32 +#define ASM_CHAR_3 33 +#define ASM_CHAR_4 34 +#define ASM_CHAR_5 35 +#define ASM_CHAR_6 36 +#define ASM_CHAR_7 37 +#define ASM_CHAR_8 38 +#define ASM_CHAR_9 39 +#define ASM_CHAR_A 41 +#define ASM_CHAR_B 42 +#define ASM_CHAR_C 43 +#define ASM_CHAR_D 44 +#define ASM_CHAR_STAR 2A +#define ASM_CHAR_HASH 23 + + +unsigned char readkey() +{ + volatile unsigned char key = 0; + __asm + INPUT _key, port_kb_low +xch1: + SRA _key + JUMP NC, xch4 + LOAD _key, ASM_CHAR_1 + JUMP xchno + +xch4: + SRA _key + JUMP NC, xch7 + LOAD _key, ASM_CHAR_4 + JUMP xchno + +xch7: + SRA _key + JUMP NC, xchs + LOAD _key, ASM_CHAR_7 + JUMP xchno + +xchs: + SRA _key + JUMP NC, xch2 + LOAD _key, ASM_CHAR_STAR + JUMP xchno + +xch2: + SRA _key + JUMP NC, xch5 + LOAD _key, ASM_CHAR_2 + JUMP xchno + +xch5: + SRA _key + JUMP NC, xch8 + LOAD _key, ASM_CHAR_5 + JUMP xchno + +xch8: + SRA _key + JUMP NC, xch0 + LOAD _key, ASM_CHAR_8 + JUMP xchno + +xch0: + SRA _key + JUMP NC, xch3 + LOAD _key, ASM_CHAR_0 + JUMP xchno + +xch3: + INPUT _key, port_kb_high + SRA _key + JUMP NC, xch6 + LOAD _key, ASM_CHAR_3 + JUMP xchno + +xch6: + SRA _key + JUMP NC, xch9 + LOAD _key, ASM_CHAR_6 + JUMP xchno + +xch9: + SRA _key + JUMP NC, xchm + LOAD _key, ASM_CHAR_9 + JUMP xchno + +xchm: + SRA _key + JUMP NC, xcha + LOAD _key, ASM_CHAR_HASH + JUMP xchno + +xcha: + SRA _key + JUMP NC, xchb + LOAD _key, ASM_CHAR_A + JUMP xchno + +xchb: + SRA _key + JUMP NC, xchc + LOAD _key, ASM_CHAR_B + JUMP xchno + +xchc: + SRA _key + JUMP NC, xchd + LOAD _key, ASM_CHAR_C + JUMP xchno + +xchd: + SRA _key + JUMP NC, xchno + LOAD _key, ASM_CHAR_D + +xchno: + + __endasm; + + return key; +} + + + + + + + + +#endif \ No newline at end of file diff -NaurbB sdcc-src-3.1.0/device/include/pblaze/lcd.h sdcc-src-3.1.0-pblaze/device/include/pblaze/lcd.h --- sdcc-src-3.1.0/device/include/pblaze/lcd.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/include/pblaze/lcd.h 2011-08-23 15:56:36.000000000 +0200 @@ -0,0 +1,96 @@ +/* + * lcd.h - LCD peripheral functions header file for FITKit + * + * adopted for SDCC and picoBlaze port by Zbynek Krivka, 2010 <krivka @ fit.vutbr.cz> + * +*/ + +#ifndef __LCD_H__ +#define __LCD_H__ + +#include "delay.h" +#include "port.h" + +#define port_lcd_high 41 +#define port_lcd_low 40 +#define LCD_CLEAR_DISPLAY 01 +#define LCD_wr(arg) __port_write(0x40, (arg)); __port_write(0x41, 01) +#define MIN_PAUSE 10 + +void LCD_clear(void); +void LCD_init(void); +void LCD_set_cursor(void); +void LCD_write(unsigned char ch); + +void LCD_clear(void) +{ + __asm + ; LCD clear + LOAD s6, LCD_CLEAR_DISPLAY + OUTPUT s6, port_lcd_low + LOAD s6, 00 + OUTPUT s6, port_lcd_high + __endasm; + delay(MIN_PAUSE); +} + +void LCD_set_cursor() +{ + __asm; + ; LCD - set cursor at the line beginning + LOAD s6, 80 + OUTPUT s6, port_lcd_low + LOAD s6, 00 + OUTPUT s6, port_lcd_high + __endasm; + delay(MIN_PAUSE); +} + +void LCD_init() +{ + __asm + ; LCD clear + LOAD s6, LCD_CLEAR_DISPLAY + OUTPUT s6, port_lcd_low + LOAD s6, 00 + OUTPUT s6, port_lcd_high + __endasm; + delay(MIN_PAUSE); + __asm + ; LCD function set - 8-bit carry, display consists of 2 parts, font 5x8 + LOAD s6, 38 + OUTPUT s6, port_lcd_low + LOAD s6, 00 + OUTPUT s6, port_lcd_high + __endasm; + delay(MIN_PAUSE); + __asm + ; LCD display - show the cursor, turn the display ON + LOAD s6, 0E + OUTPUT s6, port_lcd_low + LOAD s6, 00 + OUTPUT s6, port_lcd_high + __endasm; + delay(MIN_PAUSE); + __asm + ; LCD entry mode - increment cursor address automatically + LOAD s6, 06 + OUTPUT s6, port_lcd_low + LOAD s6, 00 + OUTPUT s6, port_lcd_high + __endasm; + + LCD_set_cursor(); + + delay(MIN_PAUSE); +} + +void LCD_write(unsigned char ch) +{ + __port_write(0x40, ch); + __port_write(0x41, 01); +} + +#endif + + diff -NaurbB sdcc-src-3.1.0/device/include/pblaze/limits.h sdcc-src-3.1.0-pblaze/device/include/pblaze/limits.h --- sdcc-src-3.1.0/device/include/pblaze/limits.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/include/pblaze/limits.h 2011-08-23 15:56:36.000000000 +0200 @@ -0,0 +1,51 @@ +/*------------------------------------------------------------------------- + limits.h - ANSI defines constants for sizes of integral types + + Adopted for the picoBlaze port by Zbynek Krivka + [ krivka @ fit.vutbr.cz ] 2010 + + Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999) + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ + +#ifndef __LIMITS_H +#define __LIMITS_H 1 + +#define CHAR_BIT 8 /* bits in a char */ +#define CHAR_MAX 127 +#define CHAR_MIN -128 +#define SCHAR_MAX CHAR_MAX +#define SCHAR_MIN CHAR_MIN +#define UCHAR_MAX 0xff +#define UCHAR_MIN 0 +#define INT_MIN -32768 +#define INT_MAX 32767 +#define SHRT_MAX INT_MAX +#define SHRT_MIN INT_MIN +#define UINT_MAX 0xffff +#define UINT_MIN 0 +#define USHRT_MAX UINT_MAX +#define USHRT_MIN UINT_MIN +#define LONG_MIN -2147483648 +#define LONG_MAX 2147483647 +#define ULONG_MAX 0xffffffff +#define ULONG_MIN 0 + +#endif diff -NaurbB sdcc-src-3.1.0/device/include/pblaze/math.h sdcc-src-3.1.0-pblaze/device/include/pblaze/math.h --- sdcc-src-3.1.0/device/include/pblaze/math.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/include/pblaze/math.h 2011-08-23 15:56:36.000000000 +0200 @@ -0,0 +1,80 @@ +/* + * math.h - Basic Mathematical (decimal only) functions header file + * + * adopted for SDCC and picoBlaze port by Zbynek Krivka, 2010 <krivka @ fit.vutbr.cz> + * +*/ + +#ifndef __MATH_H__ +#define __MATH_H__ + +/* +#pragma library math + +#include <sdcc-lib.h> + +#define PI 3.1415926536 +#define TWO_PI 6.2831853071 +#define HALF_PI 1.5707963268 +#define QUART_PI 0.7853981634 +#define iPI 0.3183098862 +#define iTWO_PI 0.1591549431 +#define TWO_O_PI 0.6366197724 + +// EPS=B**(-t/2), where B is the radix of the floating-point representation +// and there are t base-B digits in the significand. Therefore, for floats +// EPS=2**(-12). Also define EPS2=EPS*EPS. +#define EPS 244.14062E-6 +#define EPS2 59.6046E-9 +#define XMAX 3.402823466E+38 + +union float_long +{ + float f; + long l; +}; +*/ + +/********************************************** + * Prototypes for float ANSI C math functions * + **********************************************/ + +/* Trigonometric functions */ +/* +float sinf(const float x) _MATH_REENTRANT; +float cosf(const float x) _MATH_REENTRANT; +float tanf(const float x) _MATH_REENTRANT; +float cotf(const float x) _MATH_REENTRANT; +float asinf(const float x) _MATH_REENTRANT; +float acosf(const float x) _MATH_REENTRANT; +float atanf(const float x) _MATH_REENTRANT; +float atan2f(const float x, const float y); +*/ +/* Hyperbolic functions */ +/* +float sinhf(const float x) _MATH_REENTRANT; +float coshf(const float x) _MATH_REENTRANT; +float tanhf(const float x) _MATH_REENTRANT; + +/* Exponential, logarithmic and power functions */ +/* +float expf(const float x); +float logf(const float x) _MATH_REENTRANT; +float log10f(const float x) _MATH_REENTRANT; +float powf(const float x, const float y); +float sqrtf(const float a) _MATH_REENTRANT; +*/ +/* Nearest integer, absolute value, and remainder functions */ +/* +float fabsf(const float x) _MATH_REENTRANT; +float frexpf(const float x, int *pw2); +float ldexpf(const float x, const int pw2); +float ceilf(float x) _MATH_REENTRANT; +float floorf(float x) _MATH_REENTRANT; +float modff(float x, float * y); +*/ + +unsigned int pow(const unsigned int x, const unsigned int y); +unsigned int sqrt(const unsigned int a); //_MATH_REENTRANT; + +#endif /* __MATH_H */ diff -NaurbB sdcc-src-3.1.0/device/include/pblaze/pblaze3.h sdcc-src-3.1.0-pblaze/device/include/pblaze/pblaze3.h --- sdcc-src-3.1.0/device/include/pblaze/pblaze3.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/include/pblaze/pblaze3.h 2011-08-23 15:56:36.000000000 +0200 @@ -0,0 +1,1070 @@ + +/* + * pblaze.h - PicoBlaze3 Device Library Header + * + * This file is part of the GNU PIC Library. + * + * January, 2004 + * The GNU PIC Library is maintained by, + * Vangelis Rokas <vrokas@otenet.gr> + * + * $Id: pic18f452.h 3769 2005-05-24 11:22:24Z tecodev $ + * + */ + +#ifndef __PBLAZE3_H__ +#define __PBLAZE3_H__ + +extern __sfr __at (0xf80) PORTA; +typedef union { + struct { + unsigned RA0:1; + unsigned RA1:1; + unsigned RA2:1; + unsigned RA3:1; + unsigned RA4:1; + unsigned RA5:1; + unsigned RA6:1; + unsigned :1; + }; + + struct { + unsigned AN0:1; + unsigned AN1:1; + unsigned AN2:1; + unsigned AN3:1; + unsigned :1; + unsigned AN4:1; + unsigned OSC2:1; + unsigned :1; + }; + + struct { + unsigned :1; + unsigned :1; + unsigned VREFM:1; + unsigned VREFP:1; + unsigned T0CKI:1; + unsigned SS:1; + unsigned CLK0:1; + unsigned :1; + }; + + struct { + unsigned :1; + unsigned :1; + unsigned :1; + unsigned :1; + unsigned :1; + unsigned LVDIN:1; + unsigned :1; + unsigned :1; + }; +} __PORTAbits_t; + +extern volatile __PORTAbits_t __at (0xf80) PORTAbits; + +extern __sfr __at (0xf81) PORTB; +typedef union { + struct { + unsigned RB0:1; + unsigned RB1:1; + unsigned RB2:1; + unsigned RB3:1; + unsigned RB4:1; + unsigned RB5:1; + unsigned RB6:1; + unsigned RB7:1; + }; + + struct { + unsigned INT0:1; + unsigned INT1:1; + unsigned INT2:1; + unsigned INT3:1; + unsigned :1; + unsigned :1; + unsigned :1; + unsigned :1; + }; +} __PORTBbits_t; + +extern volatile __PORTBbits_t __at (0xf81) PORTBbits; + +extern __sfr __at (0xf82) PORTC; +typedef union { + struct { + unsigned RC0:1; + unsigned RC1:1; + unsigned RC2:1; + unsigned RC3:1; + unsigned RC4:1; + unsigned RC5:1; + unsigned RC6:1; + unsigned RC7:1; + }; + + struct { + unsigned T1OSO:1; + unsigned T1OSI:1; + unsigned :1; + unsigned SCK:1; + unsigned SDI:1; + unsigned SDO:1; + unsigned TX:1; + unsigned RX:1; + }; + + struct { + unsigned T1CKI:1; + unsigned CCP2:1; + unsigned CCP1:1; + unsigned SCL:1; + unsigned SDA:1; + unsigned :1; + unsigned CK:1; + unsigned DT:1; + }; +} __PORTCbits_t; + +extern volatile __PORTCbits_t __at (0xf82) PORTCbits; + +extern __sfr __at (0xf83) PORTD; +typedef union { + struct { + unsigned RD0:1; + unsigned RD1:1; + unsigned RD2:1; + unsigned RD3:1; + unsigned RD4:1; + unsigned RD5:1; + unsigned RD6:1; + unsigned RD7:1; + }; + + struct { + unsigned AD0:1; + unsigned AD1:1; + unsigned AD2:1; + unsigned AD3:1; + unsigned AD4:1; + unsigned AD5:1; + unsigned AD6:1; + unsigned AD7:1; + }; +} __PORTDbits_t; + +extern volatile __PORTDbits_t __at (0xf83) PORTDbits; + +extern __sfr __at (0xf84) PORTE; +typedef union { + struct { + unsigned RE0:1; + unsigned RE1:1; + unsigned RE2:1; + unsigned :1; + unsigned :1; + unsigned :1; + unsigned :1; + unsigned :1; + }; + + struct { + unsigned ALE:1; + unsigned OE:1; + unsigned WRL:1; + unsigned WRH:1; + unsigned :1; + unsigned :1; + unsigned :1; + unsigned CCP2:1; + }; + + struct { + unsigned AN5:1; + unsigned :1; + unsigned :1; + unsigned :1; + unsigned :1; + unsigned :1; + unsigned :1; + unsigned :1; + }; +} __PORTEbits_t; + +extern volatile __PORTEbits_t __at (0xf84) PORTEbits; + +extern __sfr __at (0xf89) LATA; +typedef union { + struct { + unsigned LATA0:1; + unsigned LATA1:1; + unsigned LATA2:1; + unsigned LATA3:1; + unsigned LATA4:1; + unsigned LATA5:1; + unsigned LATA6:1; + unsigned :1; + }; +} __LATAbits_t; + +extern volatile __LATAbits_t __at (0xf89) LATAbits; + +extern __sfr __at (0xf8a) LATB; +typedef union { + struct { + unsigned LATB0:1; + unsigned LATB1:1; + unsigned LATB2:1; + unsigned LATB3:1; + unsigned LATB4:1; + unsigned LATB5:1; + unsigned LATB6:1; + unsigned LATB7:1; + }; +} __LATBbits_t; + +extern volatile __LATBbits_t __at (0xf8a) LATBbits; + +extern __sfr __at (0xf8b) LATC; +typedef union { + struct { + unsigned LATC0:1; + unsigned LATC1:1; + unsigned LATC2:1; + unsigned LATC3:1; + unsigned LATC4:1; + unsigned LATC5:1; + unsigned LATC6:1; + unsigned LATC7:1; + }; +} __LATCbits_t; + +extern volatile __LATCbits_t __at (0xf8b) LATCbits; + +extern __sfr __at (0xf8c) LATD; +typedef union { + struct { + unsigned LATD0:1; + unsigned LATD1:1; + unsigned LATD2:1; + unsigned LATD3:1; + unsigned LATD4:1; + unsigned LATD5:1; + unsigned LATD6:1; + unsigned LATD7:1; + }; +} __LATDbits_t; + +extern volatile __LATDbits_t __at (0xf8c) LATDbits; + +extern __sfr __at (0xf8d) LATE; +typedef union { + struct { + unsigned LATE0:1; + unsigned LATE1:1; + unsigned LATE2:1; + unsigned LATE3:1; + unsigned LATE4:1; + unsigned LATE5:1; + unsigned LATE6:1; + unsigned LATE7:1; + }; +} __LATEbits_t; + +extern volatile __LATEbits_t __at (0xf8d) LATEbits; + +extern __sfr __at (0xf92) TRISA; +typedef union { + struct { + unsigned TRISA0:1; + unsigned TRISA1:1; + unsigned TRISA2:1; + unsigned TRISA3:1; + unsigned TRISA4:1; + unsigned TRISA5:1; + unsigned TRISA6:1; + unsigned :1; + }; +} __TRISAbits_t; + +extern volatile __TRISAbits_t __at (0xf92) TRISAbits; + +extern __sfr __at (0xf93) TRISB; +typedef union { + struct { + unsigned TRISB0:1; + unsigned TRISB1:1; + unsigned TRISB2:1; + unsigned TRISB3:1; + unsigned TRISB4:1; + unsigned TRISB5:1; + unsigned TRISB6:1; + unsigned TRISB7:1; + }; +} __TRISBbits_t; + +extern volatile __TRISBbits_t __at (0xf93) TRISBbits; + +extern __sfr __at (0xf94) TRISC; +typedef union { + struct { + unsigned TRISC0:1; + unsigned TRISC1:1; + unsigned TRISC2:1; + unsigned TRISC3:1; + unsigned TRISC4:1; + unsigned TRISC5:1; + unsigned TRISC6:1; + unsigned TRISC7:1; + }; +} __TRISCbits_t; + +extern volatile __TRISCbits_t __at (0xf94) TRISCbits; + +extern __sfr __at (0xf95) TRISD; +typedef union { + struct { + unsigned TRISD0:1; + unsigned TRISD1:1; + unsigned TRISD2:1; + unsigned TRISD3:1; + unsigned TRISD4:1; + unsigned TRISD5:1; + unsigned TRISD6:1; + unsigned TRISD7:1; + }; +} __TRISDbits_t; + +extern volatile __TRISDbits_t __at (0xf95) TRISDbits; + +extern __sfr __at (0xf96) TRISE; +typedef union { + struct { + unsigned TRISE0:1; + unsigned TRISE1:1; + unsigned TRISE2:1; + unsigned :1; + unsigned PSPMODE:1; + unsigned IBOV:1; + unsigned OBF:1; + unsigned IBF:1; + }; +} __TRISEbits_t; + +extern volatile __TRISEbits_t __at (0xf96) TRISEbits; + +extern __sfr __at (0xf9d) PIE1; +typedef union { + struct { + unsigned TMR1IE:1; + unsigned TMR2IE:1; + unsigned CCP1IE:1; + unsigned SSPIE:1; + unsigned TXIE:1; + unsigned RCIE:1; + unsigned ADIE:1; + unsigned PSPIE:1; + }; +} __PIE1bits_t; + +extern volatile __PIE1bits_t __at (0xf9d) PIE1bits; + +extern __sfr __at (0xf9e) PIR1; +typedef union { + struct { + unsigned TMR1IF:1; + unsigned TMR2IF:1; + unsigned CCP1IF:1; + unsigned SSPIF:1; + unsigned TXIF:1; + unsigned RCIF:1; + unsigned ADIF:1; + unsigned PSPIF:1; + }; +} __PIR1bits_t; + +extern volatile __PIR1bits_t __at (0xf9e) PIR1bits; + +extern __sfr __at (0xf9f) IPR1; +typedef union { + struct { + unsigned TMR1IP:1; + unsigned TMR2IP:1; + unsigned CCP1IP:1; + unsigned SSPIP:1; + unsigned TXIP:1; + unsigned RCIP:1; + unsigned ADIP:1; + unsigned PSPIP:1; + }; +} __IPR1bits_t; + +extern volatile __IPR1bits_t __at (0xf9f) IPR1bits; + +extern __sfr __at (0xfa0) PIE2; +typedef union { + struct { + unsigned CCP2IE:1; + unsigned TMR3IE:1; + unsigned LVDIE:1; + unsigned BCLIE:1; + unsigned EEIE:1; + unsigned :1; + unsigned :1; + unsigned :1; + }; +} __PIE2bits_t; + +extern volatile __PIE2bits_t __at (0xfa0) PIE2bits; + +extern __sfr __at (0xfa1) PIR2; +typedef union { + struct { + unsigned CCP2IF:1; + unsigned TMR3IF:1; + unsigned LVDIF:1; + unsigned BCLIF:1; + unsigned EEIF:1; + unsigned :1; + unsigned :1; + unsigned :1; + }; +} __PIR2bits_t; + +extern volatile __PIR2bits_t __at (0xfa1) PIR2bits; + +extern __sfr __at (0xfa2) IPR2; +typedef union { + struct { + unsigned CCP2IP:1; + unsigned TMR3IP:1; + unsigned LVDIP:1; + unsigned BCLIP:1; + unsigned EEIP:1; + unsigned :1; + unsigned :1; + unsigned :1; + }; +} __IPR2bits_t; + +extern volatile __IPR2bits_t __at (0xfa2) IPR2bits; + +extern __sfr __at (0xfa6) EECON1; +typedef union { + struct { + unsigned RD:1; + unsigned WR:1; + unsigned WREN:1; + unsigned WRERR:1; + unsigned FREE:1; + unsigned :1; + unsigned CFGS:1; + unsigned EEPGD:1; + }; +} __EECON1bits_t; + +extern volatile __EECON1bits_t __at (0xfa6) EECON1bits; + +extern __sfr __at (0xfa7) EECON2; +extern __sfr __at (0xfa8) EEDATA; +extern __sfr __at (0xfa9) EEADR; +extern __sfr __at (0xfab) RCSTA; +typedef union { + struct { + unsigned RX9D:1; + unsigned OERR:1; + unsigned FERR:1; + unsigned ADDEN:1; + unsigned CREN:1; + unsigned SREN:1; + unsigned RX9:1; + unsigned SPEN:1; + }; +} __RCSTAbits_t; + +extern volatile __RCSTAbits_t __at (0xfab) RCSTAbits; + +extern __sfr __at (0xfac) TXSTA; +typedef union { + struct { + unsigned TX9D:1; + unsigned TRMT:1; + unsigned BRGH:1; + unsigned :1; + unsigned SYNC:1; + unsigned TXEN:1; + unsigned TX9:1; + unsigned CSRC:1; + }; +} __TXSTAbits_t; + +extern volatile __TXSTAbits_t __at (0xfac) TXSTAbits; + +extern __sfr __at (0xfad) TXREG; +extern __sfr __at (0xfae) RCREG; +extern __sfr __at (0xfaf) SPBRG; +extern __sfr __at (0xfb1) T3CON; +typedef union { + struct { + unsigned TMR3ON:1; + unsigned TMR3CS:1; + unsigned T3SYNC:1; + unsigned T3CCP1:1; + unsigned T3CKPS0:1; + unsigned T3CKPS1:1; + unsigned T3CCP2:1; + unsigned RD16:1; + }; +} __T3CONbits_t; + +extern volatile __T3CONbits_t __at (0xfb1) T3CONbits; + +extern __sfr __at (0xfb2) TMR3L; +extern __sfr __at (0xfb3) TMR3H; +extern __sfr __at (0xfba) CCP2CON; +typedef union { + struct { + unsigned CCP2M0:1; + unsigned CCP2M1:1; + unsigned CCP2M2:1; + unsigned CCP2M3:1; + unsigned DCCP2Y:1; + unsigned DCCP2X:1; + unsigned :1; + unsigned :1; + }; +} __CCP2CONbits_t; + +extern volatile __CCP2CONbits_t __at (0xfba) CCP2CONbits; + +extern __sfr __at (0xfbb) CCPR2L; +extern __sfr __at (0xfbc) CCPR2H; +extern __sfr __at (0xfbd) CCP1CON; +typedef union { + struct { + unsigned CCP1M0:1; + unsigned CCP1M1:1; + unsigned CCP1M2:1; + unsigned CCP1M3:1; + unsigned DCCP1Y:1; + unsigned DCCP1X:1; + unsigned :1; + unsigned :1; + }; +} __CCP1CONbits_t; + +extern volatile __CCP1CONbits_t __at (0xfbd) CCP1CONbits; + +extern __sfr __at (0xfbe) CCPR1L; +extern __sfr __at (0xfbf) CCPR1H; +extern __sfr __at (0xfc1) ADCON1; +typedef union { + struct { + unsigned PCFG0:1; + unsigned PCFG1:1; + unsigned PCFG2:1; + unsigned PCFG3:1; + unsigned :1; + unsigned :1; + unsigned ADCS2:1; + unsigned ADFM:1; + }; +} __ADCON1bits_t; + +extern volatile __ADCON1bits_t __at (0xfc1) ADCON1bits; + +extern __sfr __at (0xfc2) ADCON0; +typedef union { + struct { + unsigned ADON:1; + unsigned :1; + unsigned GO:1; + unsigned CHS0:1; + unsigned CHS1:1; + unsigned CHS2:1; + unsigned ADCS0:1; + unsigned ADCS1:1; + }; +} __ADCON0bits_t; + +extern volatile __ADCON0bits_t __at (0xfc2) ADCON0bits; + +extern __sfr __at (0xfc3) ADRESL; +extern __sfr __at (0xfc4) ADRESH; +extern __sfr __at (0xfc5) SSPCON2; +typedef union { + struct { + unsigned SEN:1; + unsigned RSEN:1; + unsigned PEN:1; + unsigned RCEN:1; + unsigned ACKEN:1; + unsigned ACKDT:1; + unsigned ACKSTAT:1; + unsigned GCEN:1; + }; +} __SSPCON2bits_t; + +extern volatile __SSPCON2bits_t __at (0xfc5) SSPCON2bits; + +extern __sfr __at (0xfc6) SSPCON1; +typedef union { + struct { + unsigned SSPM0:1; + unsigned SSPM1:1; + unsigned SSPM2:1; + unsigned SSPM3:1; + unsigned CKP:1; + unsigned SSPEN:1; + unsigned SSPOV:1; + unsigned WCOL:1; + }; +} __SSPCON1bits_t; + +extern volatile __SSPCON1bits_t __at (0xfc6) SSPCON1bits; + +extern __sfr __at (0xfc7) SSPSTAT; +typedef union { + struct { + unsigned BF:1; + unsigned UA:1; + unsigned R_W:1; + unsigned S:1; + unsigned P:1; + unsigned D_A:1; + unsigned CKE:1; + unsigned SMP:1; + }; +} __SSPSTATbits_t; + +extern volatile __SSPSTATbits_t __at (0xfc7) SSPSTATbits; + +extern __sfr __at (0xfc8) SSPADD; +extern __sfr __at (0xfc9) SSPBUF; +extern __sfr __at (0xfca) T2CON; +typedef union { + struct { + unsigned T2CKPS0:1; + unsigned T2CKPS1:1; + unsigned TMR2ON:1; + unsigned TOUTPS0:1; + unsigned TOUTPS1:1; + unsigned TOUTPS2:1; + unsigned TOUTPS3:1; + unsigned :1; + }; +} __T2CONbits_t; + +extern volatile __T2CONbits_t __at (0xfca) T2CONbits; + +extern __sfr __at (0xfcb) PR2; +extern __sfr __at (0xfcc) TMR2; +extern __sfr __at (0xfcd) T1CON; +typedef union { + struct { + unsigned TMR1ON:1; + unsigned TMR1CS:1; + unsigned NOT_T1SYNC:1; + unsigned T1OSCEN:1; + unsigned T1CKPS0:1; + unsigned T1CKPS1:1; + unsigned :1; + unsigned RD16:1; + }; +} __T1CONbits_t; + +extern volatile __T1CONbits_t __at (0xfcd) T1CONbits; + +extern __sfr __at (0xfce) TMR1L; +extern __sfr __at (0xfcf) TMR1H; +extern __sfr __at (0xfd0) RCON; +typedef union { + struct { + unsigned BOR:1; + unsigned POR:1; + unsigned PD:1; + unsigned TO:1; + unsigned RI:1; + unsigned :1; + unsigned :1; + unsigned IPEN:1; + }; +} __RCONbits_t; + +extern volatile __RCONbits_t __at (0xfd0) RCONbits; + +extern __sfr __at (0xfd1) WDTCON; +typedef union { + struct { + unsigned SWDTEN:1; + unsigned :1; + unsigned :1; + unsigned :1; + unsigned :1; + unsigned :1; + unsigned :1; + unsigned :1; + }; + + struct { + unsigned SWDTE:1; + unsigned :1; + unsigned :1; + unsigned :1; + unsigned :1; + unsigned :1; + unsigned :1; + unsigned :1; + }; +} __WDTCONbits_t; + +extern volatile __WDTCONbits_t __at (0xfd1) WDTCONbits; + +extern __sfr __at (0xfd2) LVDCON; +typedef union { + struct { + unsigned LVDL0:1; + unsigned LVDL1:1; + unsigned LVDL2:1; + unsigned LVDL3:1; + unsigned LVDEN:1; + unsigned VRST:1; + unsigned :1; + unsigned :1; + }; + + struct { + unsigned LVV0:1; + unsigned LVV1:1; + unsigned LVV2:1; + unsigned LVV3:1; + unsigned :1; + unsigned BGST:1; + unsigned :1; + unsigned :1; + }; +} __LVDCONbits_t; + +extern volatile __LVDCONbits_t __at (0xfd2) LVDCONbits; + +extern __sfr __at (0xfd3) OSCCON; +typedef union { + struct { + unsigned SCS:1; + unsigned :1; + unsigned :1; + unsigned :1; + unsigned :1; + unsigned :1; + unsigned :1; + unsigned :1; + }; +} __OSCCONbits_t; + +extern volatile __OSCCONbits_t __at (0xfd3) OSCCONbits; + +extern __sfr __at (0xfd5) T0CON; +typedef union { + struct { + unsigned T0PS0:1; + unsigned T0PS1:1; + unsigned T0PS2:1; + unsigned PSA:1; + unsigned T0SE:1; + unsigned T0CS:1; + unsigned T08BIT:1; + unsigned TMR0ON:1; + }; +} __T0CONbits_t; + +extern volatile __T0CONbits_t __at (0xfd5) T0CONbits; + +extern __sfr __at (0xfd6) TMR0L; +extern __sfr __at (0xfd7) TMR0H; +extern __sfr __at (0xfd8) STATUS; +typedef union { + struct { + unsigned C:1; + unsigned DC:1; + unsigned Z:1; + unsigned OV:1; + unsigned N:1; + unsigned :1; + unsigned :1; + unsigned :1; + }; +} __STATUSbits_t; + +extern volatile __STATUSbits_t __at (0xfd8) STATUSbits; + +extern __sfr __at (0xfd9) FSR2L; +extern __sfr __at (0xfda) FSR2H; +extern __sfr __at (0xfdb) PLUSW2; +extern __sfr __at (0xfdc) PREINC2; +extern __sfr __at (0xfdd) POSTDEC2; +extern __sfr __at (0xfde) POSTINC2; +extern __sfr __at (0xfdf) INDF2; +extern __sfr __at (0xfe0) BSR; +extern __sfr __at (0xfe1) FSR1L; +extern __sfr __at (0xfe2) FSR1H; +extern __sfr __at (0xfe3) PLUSW1; +extern __sfr __at (0xfe4) PREINC1; +extern __sfr __at (0xfe5) POSTDEC1; +extern __sfr __at (0xfe6) POSTINC1; +extern __sfr __at (0xfe7) INDF1; +extern __sfr __at (0xfe8) WREG; +extern __sfr __at (0xfe9) FSR0L; +extern __sfr __at (0xfea) FSR0H; +extern __sfr __at (0xfeb) PLUSW0; +extern __sfr __at (0xfec) PREINC0; +extern __sfr __at (0xfed) POSTDEC0; +extern __sfr __at (0xfee) POSTINC0; +extern __sfr __at (0xfef) INDF0; +extern __sfr __at (0xff0) INTCON3; +typedef union { + struct { + unsigned INT1F:1; + unsigned INT2F:1; + unsigned :1; + unsigned INT1E:1; + unsigned INT2E:1; + unsigned :1; + unsigned INT1P:1; + unsigned INT2P:1; + }; + + struct { + unsigned INT1IF:1; + unsigned INT2IF:1; + unsigned :1; + unsigned INT1IE:1; + unsigned INT2IE:1; + unsigned :1; + unsigned INT1IP:1; + unsigned INT2IP:1; + }; +} __INTCON3bits_t; + +extern volatile __INTCON3bits_t __at (0xff0) INTCON3bits; + +extern __sfr __at (0xff1) INTCON2; +typedef union { + struct { + unsigned RBIP:1; + unsigned :1; + unsigned T0IP:1; + unsigned :1; + unsigned INTEDG2:1; + unsigned INTEDG1:1; + unsigned INTEDG0:1; + unsigned RBPU:1; + }; +} __INTCON2bits_t; + +extern volatile __INTCON2bits_t __at (0xff1) INTCON2bits; + +extern __sfr __at (0xff2) INTCON; +typedef union { + struct { + unsigned RBIF:1; + unsigned INT0F:1; + unsigned T0IF:1; + unsigned RBIE:1; + unsigned INT0E:1; + unsigned T0IE:1; + unsigned PEIE:1; + unsigned GIE:1; + }; +} __INTCONbits_t; + +extern volatile __INTCONbits_t __at (0xff2) INTCONbits; + +extern __sfr __at (0xff3) PRODL; +extern __sfr __at (0xff4) PRODH; +extern __sfr __at (0xff5) TABLAT; +extern __sfr __at (0xff6) TBLPTRL; +extern __sfr __at (0xff7) TBLPTRH; +extern __sfr __at (0xff8) TBLPTRU; +extern __sfr __at (0xff9) PCL; +extern __sfr __at (0xffa) PCLATH; +extern __sfr __at (0xffb) PCLATU; +extern __sfr __at (0xffc) STKPTR; +typedef union { + struct { + unsigned STKPTR0:1; + unsigned STKPTR1:1; + unsigned STKPTR2:1; + unsigned STKPTR3:1; + unsigned STKPTR4:1; + unsigned :1; + unsigned STKUNF:1; + unsigned STKFUL:1; + }; +} __STKPTRbits_t; + +extern volatile __STKPTRbits_t __at (0xffc) STKPTRbits; + +extern __sfr __at (0xffd) TOSL; +extern __sfr __at (0xffe) TOSH; +extern __sfr __at (0xfff) TOSU; + + +/* Configuration registers locations */ +#define __CONFIG1H 0x300001 +#define __CONFIG2L 0x300002 +#define __CONFIG2H 0x300003 +#define __CONFIG3H 0x300005 +#define __CONFIG4L 0x300006 +#define __CONFIG5L 0x300008 +#define __CONFIG5H 0x300009 +#define __CONFIG6L 0x30000A +#define __CONFIG6H 0x30000B +#define __CONFIG7L 0x30000C +#define __CONFIG7H 0x30000D + + + +/* Oscillator 1H options */ +#define _OSC_RC_OSC2_1H 0xFF /* RC-OSC2 as RA6 */ +#define _OSC_HS_PLL_1H 0xFE /* HS-PLL Enabled */ +#define _OSC_EC_OSC2_RA6_1H 0xFD /* EC-OSC2 as RA6 */ +#define _OSC_EC_OSC2_Clock_Out_1H 0xFC /* EC-OSC2 as Clock_Out */ +#define _OSC_RC_1H 0xFB /* RC */ +#define _OSC_HS_1H 0xFA /* HS */ +#define _OSC_XT_1H 0xF9 /* XT */ +#define _OSC_LP_1H 0xF8 /* LP */ + +/* Osc. Switch Enable 1H options */ +#define _OSCS_OFF_1H 0xFF /* Disabled */ +#define _OSCS_ON_1H 0xDF /* Enabled */ + +/* Power Up Timer 2L options */ +#define _PUT_OFF_2L 0xFF /* Disabled */ +#define _PUT_ON_2L 0xFE /* Enabled */ + +/* Brown Out Detect 2L options */ +#define _BODEN_ON_2L 0xFF /* Enabled */ +#define _BODEN_OFF_2L 0xFD /* Disabled */ + +/* Brown Out Voltage 2L options */ +#define _BODENV_2_0V_2L 0xFF /* 2.0V */ +#define _BODENV_2_7V_2L 0xFB /* 2.7V */ +#define _BODENV_4_2V_2L 0xF7 /* 4.2V */ +#define _BODENV_4_5V_2L 0xF3 /* 4.5V */ + +/* Watchdog Timer 2H options */ +#define _WDT_ON_2H 0xFF /* Enabled */ +#define _WDT_OFF_2H 0xFE /* Disabled */ + +/* Watchdog Postscaler 2H options */ +#define _WDTPS_1_128_2H 0xFF /* 1:128 */ +#define _WDTPS_1_64_2H 0xFD /* 1:64 */ +#define _WDTPS_1_32_2H 0xFB /* 1:32 */ +#define _WDTPS_1_16_2H 0xF9 /* 1:16 */ +#define _WDTPS_1_8_2H 0xF7 /* 1:8 */ +#define _WDTPS_1_4_2H 0xF5 /* 1:4 */ +#define _WDTPS_1_2_2H 0xF3 /* 1:2 */ +#define _WDTPS_1_1_2H 0xF1 /* 1:1 */ + +/* CCP2 Mux 3H options */ +#define _CCP2MUX_RC1_3H 0xFF /* RC1 */ +#define _CCP2MUX_RB3_3H 0xFE /* RB3 */ + +/* Low Voltage Program 4L options */ +#define _LVP_ON_4L 0xFF /* Enabled */ +#define _LVP_OFF_4L 0xFB /* Disabled */ + +/* Background Debug 4L options */ +#define _BACKBUG_OFF_4L 0xFF /* Disabled */ +#define _BACKBUG_ON_4L 0x7F /* Enabled */ + +/* Stack Overflow Reset 4L options */ +#define _STVR_ON_4L 0xFF /* Enabled */ +#define _STVR_OFF_4L 0xFE /* Disabled */ + +/* Code Protect 00200-01FFF 5L options */ +#define _CP_0_OFF_5L 0xFF /* Disabled */ +#define _CP_0_ON_5L 0xFE /* Enabled */ + +/* Code Protect 02000-03FFF 5L options */ +#define _CP_1_OFF_5L 0xFF /* Disabled */ +#define _CP_1_ON_5L 0xFD /* Enabled */ + +/* Code Protect 04000-05FFF 5L options */ +#define _CP_2_OFF_5L 0xFF /* Disabled */ +#define _CP_2_ON_5L 0xFB /* Enabled */ + +/* Code Protect 06000-07FFF 5L options */ +#define _CP_3_OFF_5L 0xFF /* Disabled */ +#define _CP_3_ON_5L 0xF7 /* Enabled */ + +/* Data EE Read Protect 5H options */ +#define _CPD_OFF_5H 0xFF /* Disabled */ +#define _CPD_ON_5H 0x7F /* Enabled */ + +/* Code Protect Boot 5H options */ +#define _CPB_OFF_5H 0xFF /* Disabled */ +#define _CPB_ON_5H 0xBF /* Enabled */ + +/* Table Write Protect 00200-01FFF 6L options */ +#define _WRT_0_OFF_6L 0xFF /* Disabled */ +#define _WRT_0_ON_6L 0xFE /* Enabled */ + +/* Table Write Protect 02000-03FFF 6L options */ +#define _WRT_1_OFF_6L 0xFF /* Disabled */ +#define _WRT_1_ON_6L 0xFD /* Enabled */ + +/* Table Write Protect 04000-05FFF 6L options */ +#define _WRT_2_OFF_6L 0xFF /* Disabled */ +#define _WRT_2_ON_6L 0xFB /* Enabled */ + +/* Table Write Protect 06000-07FFF 6L options */ +#define _WRT_3_OFF_6L 0xFF /* Disabled */ +#define _WRT_3_ON_6L 0xF7 /* Enabled */ + +/* Data EE Write Protect 6H options */ +#define _WRTD_OFF_6H 0xFF /* Disabled */ +#define _WRTD_ON_6H 0x7F /* Enabled */ + +/* Table Write Protect Boot 6H options */ +#define _WRTB_OFF_6H 0xFF /* Disabled */ +#define _WRTB_ON_6H 0xBF /* Enabled */ + +/* Config. Write Protect 6H options */ +#define _WRTC_OFF_6H 0xFF /* Disabled */ +#define _WRTC_ON_6H 0xDF /* Enabled */ + +/* Table Read Protect 00200-01FFF 7L options */ +#define _EBTR_0_OFF_7L 0xFF /* Disabled */ +#define _EBTR_0_ON_7L 0xFE /* Enabled */ + +/* Table Read Protect 02000-03FFF 7L options */ +#define _EBTR_1_OFF_7L 0xFF /* Disabled */ +#define _EBTR_1_ON_7L 0xFD /* Enabled */ + +/* Table Read Protect 04000-05FFF 7L options */ +#define _EBTR_2_OFF_7L 0xFF /* Disabled */ +#define _EBTR_2_ON_7L 0xFB /* Enabled */ + +/* Table Read Protect 06000-07FFF 7L options */ +#define _EBTR_3_OFF_7L 0xFF /* Disabled */ +#define _EBTR_3_ON_7L 0xF7 /* Enabled */ + +/* Table Read Protect Boot 7H options */ +#define _EBTRB_OFF_7H 0xFF /* Disabled */ +#define _EBTRB_ON_7H 0xBF /* Enabled */ + + +/* Device ID locations */ +#define __IDLOC0 0x200000 +#define __IDLOC1 0x200001 +#define __IDLOC2 0x200002 +#define __IDLOC3 0x200003 +#define __IDLOC4 0x200004 +#define __IDLOC5 0x200005 +#define __IDLOC6 0x200006 +#define __IDLOC7 0x200007 + + +#endif diff -NaurbB sdcc-src-3.1.0/device/include/pblaze/pblazedevices.txt sdcc-src-3.1.0-pblaze/device/include/pblaze/pblazedevices.txt --- sdcc-src-3.1.0/device/include/pblaze/pblazedevices.txt 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/include/pblaze/pblazedevices.txt 2011-08-23 15:56:36.000000000 +0200 @@ -0,0 +1,53 @@ +# +# Specification of devices supported by the PIC16 target of the +# Small Devices C Compiler (SDCC). +# +# Lines starting with a hash '#' are ignored. +# A new device specification must begin with a 'name' command. +# Numbers can be given in any way acceptable for scanf's %d, +# i.e., octal (0[0-7]*), decimal ([1-9][0-9]*), or hexadecimal +# (0[xX][0-9a-fA-F]+). +# Strings must not be quoted and may not contain whitespace! +# +# Valid commands are: +# name <name> +# Begin specification of device type <name>, e.g. 18f6720. +# Aliases 'p<name>' and 'pic<name>' will be recognized as well. +# using <name> +# Import specification from the named entry, which must be defined +# earlier. Later commands overrule imported ones. +# ramsize <size> +# This device has <size> bytes of RAM. +# split <offset> +# Addresses below <offset> refer to bank 0, addresses above <offset> +# refer to SFRs in bank 15 for references via the access bank. +# configrange <first> <last> +# Configuration registers occupy addresses <first> to <last> (both +# included). +# configword <address> <mask> <value> +# The config word at address <address> only implements the bits +# indicated via <mask> (all others will be forced to 0 by the +# compiler). +# Unless overridden in C code, use the given default <value>. +# idlocrange <first> <last> +# ID locations occupy addresses <first> to <last> (both included). +# idword <address> <value> +# Unless overridden in C code, use the given default <value>. +# + +name picoBlaze3 +ramsize 64 +split 0x40 +configrange 0x300001 0x30000d +configword 0x300001 0x27 0xff +configword 0x300002 0x0f 0xff +configword 0x300003 0x0f 0xff +configword 0x300005 0x01 0xff +configword 0x300006 0x85 0xff +configword 0x300008 0x0f 0xff +configword 0x300009 0xc0 0xff +configword 0x30000a 0x0f 0xff +configword 0x30000b 0xe0 0xff +configword 0x30000c 0x0f 0xff +configword 0x30000d 0x40 0xff +idlocrange 0x200000 0x200007 diff -NaurbB sdcc-src-3.1.0/device/include/pblaze/port.h sdcc-src-3.1.0-pblaze/device/include/pblaze/port.h --- sdcc-src-3.1.0/device/include/pblaze/port.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/include/pblaze/port.h 2011-08-23 15:56:36.000000000 +0200 @@ -0,0 +1,39 @@ +#ifndef __PORT_H__ +#define __PORT_H__ + +#define MIN_PAUSE 10 + +#include "delay.h" +/* + * port.h - port communication functions header file + * + * adopted for SDCC and picoBlaze port by Zbynek Krivka, 2010 <krivka @ fit.vutbr.cz> + * +*/ +void __port_write(unsigned char, unsigned char); +unsigned char __port_read(volatile unsigned char); + +void __port_write(unsigned char port, unsigned char arg) +{ + unsigned volatile char p; + unsigned volatile char a; + p = port; + a = arg; + __asm + OUTPUT _a, _p + __endasm; + delay(MIN_PAUSE); +} + +unsigned char __port_read(volatile unsigned char port) +{ + volatile unsigned char d = 0; + volatile unsigned char p = port; + __asm + INPUT _d, _p + __endasm; + delay(MIN_PAUSE); + return d; +} + +#endif \ No newline at end of file diff -NaurbB sdcc-src-3.1.0/device/include/pblaze/stdint.h sdcc-src-3.1.0-pblaze/device/include/pblaze/stdint.h --- sdcc-src-3.1.0/device/include/pblaze/stdint.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/include/pblaze/stdint.h 2011-08-23 15:56:36.000000000 +0200 @@ -0,0 +1,157 @@ +/*------------------------------------------------------------------------- + stdint.h - ISO C99 7.18 Integer types <stdint.h> + + Written By - Maarten Brock, sourceforge.brock@dse.nl (2005) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-------------------------------------------------------------------------*/ + +#ifndef _STDINT_H +#define _STDINT_H 1 + +/* Exact integral types. */ + +/* Signed. */ + +typedef signed char int8_t; +typedef short int int16_t; +typedef long int int32_t; + +/* Unsigned. */ +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; +typedef unsigned long int uint32_t; + + +/* Small types. */ + +/* Signed. */ +typedef signed char int_least8_t; +typedef short int int_least16_t; +typedef long int int_least32_t; + +/* Unsigned. */ +typedef unsigned char uint_least8_t; +typedef unsigned short int uint_least16_t; +typedef unsigned long int uint_least32_t; + + +/* Fast types. */ + +/* Signed. */ +typedef signed char int_fast8_t; +typedef int int_fast16_t; +typedef long int int_fast32_t; + +/* Unsigned. */ +typedef unsigned char uint_fast8_t; +typedef unsigned int uint_fast16_t; +typedef unsigned long int uint_fast32_t; + + +/* Types for `void *' pointers. */ +typedef long int intptr_t; +typedef unsigned long int uintptr_t; + + +/* Largest integral types. */ +typedef long int intmax_t; +typedef unsigned long int uintmax_t; + + +/* Limits of integral types. */ + +/* Minimum of signed integral types. */ +# define INT8_MIN (-128) +# define INT16_MIN (-32767-1) +# define INT32_MIN (-2147483647L-1) +/* Maximum of signed integral types. */ +# define INT8_MAX (127) +# define INT16_MAX (32767) +# define INT32_MAX (2147483647L) + +/* Maximum of unsigned integral types. */ +# define UINT8_MAX (255) +# define UINT16_MAX (65535) +# define UINT32_MAX (4294967295UL) + +/* Minimum of signed integral types having a minimum size. */ +# define INT_LEAST8_MIN (-128) +# define INT_LEAST16_MIN (-32767-1) +# define INT_LEAST32_MIN (-2147483647L-1) +/* Maximum of signed integral types having a minimum size. */ +# define INT_LEAST8_MAX (127) +# define INT_LEAST16_MAX (32767) +# define INT_LEAST32_MAX (2147483647L) + +/* Maximum of unsigned integral types having a minimum size. */ +# define UINT_LEAST8_MAX (255) +# define UINT_LEAST16_MAX (65535) +# define UINT_LEAST32_MAX (4294967295UL) + +/* Minimum of fast signed integral types having a minimum size. */ +# define INT_FAST8_MIN (-128) +# define INT_FAST16_MIN (-32767-1) +# define INT_FAST32_MIN (-2147483647L-1) + +/* Maximum of fast signed integral types having a minimum size. */ +# define INT_FAST8_MAX (127) +# define INT_FAST16_MAX (32767) +# define INT_FAST32_MAX (2147483647L) + +/* Maximum of fast unsigned integral types having a minimum size. */ +# define UINT_FAST8_MAX (255) +# define UINT_FAST16_MAX (65535) +# define UINT_FAST32_MAX (4294967295UL) + +/* Values to test for integral types holding `void *' pointer. */ +# define INTPTR_MIN (-2147483647L-1) +# define INTPTR_MAX (2147483647L) +# define UINTPTR_MAX (4294967295UL) + +/* Minimum for largest signed integral type. */ +# define INTMAX_MIN (-__INT32_C(-2147483647L)-1) +/* Maximum for largest signed integral type. */ +# define INTMAX_MAX (__INT32_C(2147483647L)) + +/* Maximum for largest unsigned integral type. */ +# define UINTMAX_MAX (__UINT32_C(4294967295UL)) + + +/* Limits of other integer types. */ + +/* Limits of `ptrdiff_t' type. */ +# define PTRDIFF_MIN (-2147483647L-1) +# define PTRDIFF_MAX (2147483647L) + +/* Limit of `size_t' type. */ +# define SIZE_MAX (65535) + +/* Signed. */ +# define INT8_C(c) c +# define INT16_C(c) c +# define INT32_C(c) c ## L + +/* Unsigned. */ +# define UINT8_C(c) c ## U +# define UINT16_C(c) c ## U +# define UINT32_C(c) c ## UL + +/* Maximal type. */ +# define INTMAX_C(c) c ## L +# define UINTMAX_C(c) c ## UL + + +#endif /* stdint.h */ diff -NaurbB sdcc-src-3.1.0/device/lib/Makefile.in sdcc-src-3.1.0-pblaze/device/lib/Makefile.in --- sdcc-src-3.1.0/device/lib/Makefile.in 2011-11-01 17:35:46.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/device/lib/Makefile.in 2011-12-04 13:55:53.223464300 +0100 @@ -70,6 +70,7 @@ OPT_DISABLE_Z80 = @OPT_DISABLE_Z80@ OPT_DISABLE_Z180 = @OPT_DISABLE_Z180@ OPT_DISABLE_R2K = @OPT_DISABLE_R2K@ +OPT_DISABLE_PBLAZE= @OPT_DISABLE_PBLAZE@ SOURCES_FLOAT = $(COMMON_FLOAT) \ _fscmp.c \ diff -NaurbB sdcc-src-3.1.0/device/non-free/lib/Makefile.in sdcc-src-3.1.0-pblaze/device/non-free/lib/Makefile.in --- sdcc-src-3.1.0/device/non-free/lib/Makefile.in 2011-10-25 20:43:54.000000000 +0200 +++ sdcc-src-3.1.0-pblaze/device/non-free/lib/Makefile.in 2011-12-04 13:57:07.901735700 +0100 @@ -68,6 +68,7 @@ OPT_DISABLE_PIC16 = @OPT_DISABLE_PIC16@ OPT_DISABLE_XA51 = @OPT_DISABLE_XA51@ OPT_DISABLE_Z80 = @OPT_DISABLE_Z80@ +OPT_DISABLE_PBLAZE= @OPT_DISABLE_PBLAZE@ SOURCES_FLOAT = $(COMMON_FLOAT) \ _fscmp.c \ diff -NaurbB sdcc-src-3.1.0/doc/sdcc_pblaze_instructions.txt sdcc-src-3.1.0-pblaze/doc/sdcc_pblaze_instructions.txt --- sdcc-src-3.1.0/doc/sdcc_pblaze_instructions.txt 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/doc/sdcc_pblaze_instructions.txt 2011-12-06 21:32:48.872001100 +0100 @@ -0,0 +1,57 @@ + +# ================ # +# PHASE : ADD PORT # +# ================ # +# configure +- in : sdcc\configure.in. +- near "Now handle the port selection" +- add : +AC_DO_PORT(pblaze, pblaze, PBLAZE, [Excludes the PBLAZE port]) + +- near : "Generating output files" +- add : +if test $OPT_DISABLE_PBLAZE = 0; then + AC_CONFIG_FILES([src/pblaze/Makefile]) +fi + +- near : "ENABLED Ports:" +- add : + pblaze ${enable_pblaze_port} + +# directory: +- add : +sdcc\device\include\pblaze +sdcc\src\pblaze +sdcc\tests\pblaze + +# =================== # +# PHASE : COMPILATION # +# =================== # +# decompress +tar -xjf sdcc-src-3.1.0.tar.bz2 + +# move to directory +cd sdcc + +# configure +./configure \ +--disable-mcs51-port \ +--disable-gbz80-port \ +--disable-z80-port \ +--disable-z180-port \ +--disable-avr-port \ +--disable-ds390-port \ +--disable-ds400-port \ +--disable-hc08-port \ +--disable-pic14-port \ +--disable-pic16-port \ +--disable-r2k-port \ +--disable-xa51-port \ +--disable-ucsim \ +--disable-device-lib \ +--disable-packihx + +# make +make + +# install \ No newline at end of file diff -NaurbB sdcc-src-3.1.0/sdcc_vc_in.h sdcc-src-3.1.0-pblaze/sdcc_vc_in.h --- sdcc-src-3.1.0/sdcc_vc_in.h 2011-06-10 23:19:02.000000000 +0200 +++ sdcc-src-3.1.0-pblaze/sdcc_vc_in.h 2011-12-04 15:18:59.087639400 +0100 @@ -77,6 +77,7 @@ #undef OPT_DISABLE_PIC14 #undef OPT_DISABLE_PIC16 #define OPT_DISABLE_XA51 1 +#undef OPT_DISABLE_PBLAZE #endif /* SDCC_VC_HEADER */ diff -NaurbB sdcc-src-3.1.0/sdccconf_in.h sdcc-src-3.1.0-pblaze/sdccconf_in.h --- sdcc-src-3.1.0/sdccconf_in.h 2011-10-09 20:21:10.000000000 +0200 +++ sdcc-src-3.1.0-pblaze/sdccconf_in.h 2011-12-04 13:59:25.373598600 +0100 @@ -138,6 +138,9 @@ #undef OPT_DISABLE_R2K /* XXX */ +#undef OPT_DISABLE_PBLAZE + +/* XXX */ #undef OPT_DISABLE_SDCDB /* XXX */ diff -NaurbB sdcc-src-3.1.0/src/SDCCmain.c sdcc-src-3.1.0-pblaze/src/SDCCmain.c --- sdcc-src-3.1.0/src/SDCCmain.c 2011-10-09 20:21:10.000000000 +0200 +++ sdcc-src-3.1.0-pblaze/src/SDCCmain.c 2011-12-04 14:01:09.673564200 +0100 @@ -340,6 +340,9 @@ #if !OPT_DISABLE_HC08 &hc08_port, #endif +#if !OPT_DISABLE_PBLAZE + &pblaze_port, +#endif }; #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0])) diff -NaurbB sdcc-src-3.1.0/src/json/Makefile.in sdcc-src-3.1.0-pblaze/src/json/Makefile.in --- sdcc-src-3.1.0/src/json/Makefile.in 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/Makefile.in 2011-02-07 20:04:44.000000000 +0100 @@ -0,0 +1,8 @@ +VPATH = @srcdir@ +srcdir = @srcdir@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +# Make all in this directory +include $(srcdir)/../port.mk + diff -NaurbB sdcc-src-3.1.0/src/json/device.h sdcc-src-3.1.0-pblaze/src/json/device.h --- sdcc-src-3.1.0/src/json/device.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/device.h 2011-02-07 20:04:44.000000000 +0100 @@ -0,0 +1,61 @@ +/*------------------------------------------------------------------------- + + Json + + device.c - Accomodates subtle variations in JSON devices + + Written By - Scott Dattalo scott@dattalo.com + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-------------------------------------------------------------------------*/ + +/* + PIC device abstraction + + There are dozens of variations of PIC microcontrollers. This include + file attempts to abstract those differences so that SDCC can easily + deal with them. +*/ + +#ifndef __JSON_DEVICE_H__ +#define __JSON_DEVICE_H__ + + +#define PROCESSOR_NAMES 4 +/* Processor unique attributes */ + +typedef struct JSON_device { + char *name[PROCESSOR_NAMES]; /* aliases for the processor name */ + /* RAMsize *must* be the first item to copy for 'using' */ + int RAMsize; /* size of Data RAM - VR 031120 */ + int acsSplitOfs; /* access bank split offset */ +// configWordsInfo_t cwInfo; /* configuration words info */ +// idBytesInfo_t idInfo; /* ID Locations info */ + /* next *must* be the first field NOT being copied via 'using' */ + struct JSON_device *next; /* linked list */ +} JSON_device; + +extern JSON_device *picoBlaze; + +typedef struct { + int json_flag; // JSON flag if to do the dump of iCodes in JSON format + char *json_dumpfile; // name of the JSON dump file +} json_options_t; + +extern json_options_t json_options; + + +#endif /* __JSON_DEVICE_H__ */ + diff -NaurbB sdcc-src-3.1.0/src/json/gen.c sdcc-src-3.1.0-pblaze/src/json/gen.c --- sdcc-src-3.1.0/src/json/gen.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/gen.c 2011-02-07 20:04:48.000000000 +0100 @@ -0,0 +1,1193 @@ +/*------------------------------------------------------------------------- + gen.c - source file for code generation into JSON + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! + + +-------------------------------------------------------------------------*/ + +#define D(x) do if (options.verboseAsm) {x;} while(0) + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include "SDCCglobl.h" +#include "newalloc.h" + +#include "common.h" +#include "SDCCpeeph.h" +#include "ralloc.h" +#include "gen.h" + +#include "json/json.h" + +extern int allocInfo; + +// unsigned fJSONReturnSize = 4; /* shared with ralloc.c */ + +static struct { + short xPushed; + short zPushed; + short accInUse; + short inLine; + short debugLine; + short nRegsSaved; + set *sendSet; +} _G; + +extern int json_ptrRegReq; +extern int json_nRegs; +extern struct dbuf_s *codeOutBuf; + + +static lineNode *lineHead = NULL; +static lineNode *lineCurr = NULL; + +#define LSB 0 +#define MSB16 1 +#define MSB24 2 +#define MSB32 3 + +/*-----------------------------------------------------------------*/ +/* emitcode - writes the code into a file */ +/*-----------------------------------------------------------------*/ +static void +emitcode (char *inst, char *fmt, ...) +{ + va_list ap; + char lb[INITIAL_INLINEASM]; + char *lbp = lb; + + va_start (ap, fmt); + + if (inst && *inst) { + if (fmt && *fmt) + sprintf (lb, "%s\t", inst); + else + sprintf (lb, "%s", inst); + vsprintf (lb + (strlen (lb)), fmt, ap); + } + else + vsprintf (lb, fmt, ap); + + while (isspace ((unsigned char)*lbp)) + lbp++; + + if (lbp && *lbp) + lineCurr = (lineCurr ? + connectLine (lineCurr, newLineNode (lb)) : + (lineHead = newLineNode (lb))); + lineCurr->isInline = _G.inLine; + lineCurr->isDebug = _G.debugLine; + va_end (ap); +} + +/*-----------------------------------------------------------------*/ +/* json_emitDebuggerSymbol - associate the current code location */ +/* with a debugger symbol */ +/*-----------------------------------------------------------------*/ +void +json_emitDebuggerSymbol (const char * debugSym) +{ + _G.debugLine = 1; + emitcode ("", "%s ==.", debugSym); + _G.debugLine = 0; +} + + +/*-----------------------------------------------------------------*/ +/* newAsmop - creates a new asmOp */ +/*-----------------------------------------------------------------*/ +static asmop * +newAsmop (short type) +{ + asmop *aop; + + aop = Safe_calloc (1, sizeof (asmop)); + aop->type = type; + return aop; +} + +/*-----------------------------------------------------------------*/ +/* pointerCode - returns the code for a pointer type */ +/*-----------------------------------------------------------------*/ +static int +pointerCode (sym_link * etype) +{ + + return PTR_TYPE (SPEC_OCLS (etype)); + +} + + +/*-----------------------------------------------------------------*/ +/* regsInCommon - two operands have some registers in common */ +/*-----------------------------------------------------------------*/ +static bool +regsInCommon (operand * op1, operand * op2) +{ + symbol *sym1, *sym2; + int i; + + /* if they have registers in common */ + if (!IS_SYMOP (op1) || !IS_SYMOP (op2)) + return FALSE; + + sym1 = OP_SYMBOL (op1); + sym2 = OP_SYMBOL (op2); + + if (sym1->nRegs == 0 || sym2->nRegs == 0) + return FALSE; + + for (i = 0; i < sym1->nRegs; i++) { + int j; + if (!sym1->regs[i]) + continue; + + for (j = 0; j < sym2->nRegs; j++) { + if (!sym2->regs[j]) + continue; + + if (sym2->regs[j] == sym1->regs[i]) + return TRUE; + } + } + + return FALSE; +} + +/*-----------------------------------------------------------------*/ +/* operandsEqu - equivalent */ +/*-----------------------------------------------------------------*/ +static bool +operandsEqu (operand * op1, operand * op2) +{ + symbol *sym1, *sym2; + + /* if they not symbols */ + if (!IS_SYMOP (op1) || !IS_SYMOP (op2)) + return FALSE; + + sym1 = OP_SYMBOL (op1); + sym2 = OP_SYMBOL (op2); + + /* if they are the same */ + if (sym1 == sym2) + return TRUE; + + if (strcmp (sym1->rname, sym2->rname) == 0) + return TRUE; + + + /* if left is a tmp & right is not */ + if (IS_ITEMP (op1) && + !IS_ITEMP (op2) && sym1->isspilt && (sym1->usl.spillLoc == sym2)) + return TRUE; + + if (IS_ITEMP (op2) && + !IS_ITEMP (op1) && + sym2->isspilt && sym1->level > 0 && (sym2->usl.spillLoc == sym1)) + return TRUE; + + return FALSE; +} + + +/*-----------------------------------------------------------------*/ +/* aopOp - allocates an asmop for an operand : */ +/*-----------------------------------------------------------------*/ +static void +aopOp (operand * op, iCode * ic, bool result) +{ + asmop *aop; + symbol *sym; + int i; + + if (!op) + return; + + /* if this a literal */ + if (IS_OP_LITERAL (op)) { + op->aop = aop = newAsmop (AOP_LIT); + aop->aopu.aop_lit = op->operand.valOperand; + aop->size = getSize (operandType (op)); + return; + } + + /* if already has a asmop then continue */ + if (op->aop) + return; + + /* must be load into a register */ + sym->aop = op->aop = aop = newAsmop (AOP_REG); + aop->size = sym->nRegs; + //getReg (op, aop); + +} + +/*-----------------------------------------------------------------*/ +/* freeAsmop - free up the asmop given to an operand */ +/*----------------------------------------------------------------*/ +static void +freeAsmop (operand * op, asmop * aaop, iCode * ic) +{ + asmop *aop; + + if (!op) + aop = aaop; + else + aop = op->aop; + + if (!aop) + return; + + if (op) { + op->aop = NULL; + } +} + + + +/*-----------------------------------------------------------------*/ +/* genNotFloat - generates not for float operations */ +/*-----------------------------------------------------------------*/ +static void +genNotFloat (operand * op, operand * res) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genNot - generate code for ! operation */ +/*-----------------------------------------------------------------*/ +static void +genNot (iCode * ic) +{ + +} + + +/*-----------------------------------------------------------------*/ +/* genCpl - generate code for complement */ +/*-----------------------------------------------------------------*/ +static void +genCpl (iCode * ic) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genUminusFloat - unary minus for floating points */ +/*-----------------------------------------------------------------*/ +static void +genUminusFloat (operand * op, operand * result) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genUminus - unary minus code generation */ +/*-----------------------------------------------------------------*/ +static void +genUminus (iCode * ic) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genIpush - genrate code for pushing this gets a little complex */ +/*-----------------------------------------------------------------*/ +static void +genIpush (iCode * ic) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genIpop - recover the registers: can happen only for spilling */ +/*-----------------------------------------------------------------*/ +static void +genIpop (iCode * ic) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genCall - generates a call statement */ +/*-----------------------------------------------------------------*/ +static void +genCall (iCode * ic) +{ + + +} + +/*-----------------------------------------------------------------*/ +/* genPcall - generates a call by pointer statement */ +/*-----------------------------------------------------------------*/ +static void +genPcall (iCode * ic) +{ + +} + + +/*-----------------------------------------------------------------*/ +/* genFunction - generated code for function entry */ +/*-----------------------------------------------------------------*/ +static void +genFunction (iCode * ic) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genEndFunction - generates epilogue for functions */ +/*-----------------------------------------------------------------*/ +static void +genEndFunction (iCode * ic) +{ + + +} + +/*-----------------------------------------------------------------*/ +/* genRet - generate code for return statement */ +/*-----------------------------------------------------------------*/ +static void +genRet (iCode * ic) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genLabel - generates a label */ +/*-----------------------------------------------------------------*/ +static void +genLabel (iCode * ic) +{ + /* special case never generate */ + if (IC_LABEL (ic) == entryLabel) + return; + + emitcode ("", "L%05d:", IC_LABEL (ic)->key); +} + +/*-----------------------------------------------------------------*/ +/* genGoto - generates a ljmp */ +/*-----------------------------------------------------------------*/ +static void +genGoto (iCode * ic) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genPlusIncr :- does addition with increment if possible */ +/*-----------------------------------------------------------------*/ +static bool +genPlusIncr (iCode * ic) +{ +return FALSE; +} + + +/*-----------------------------------------------------------------*/ +/* genPlus - generates code for addition */ +/*-----------------------------------------------------------------*/ +static void +genPlus (iCode * ic) +{ + + + emitcode ("add", "%d, %d",4,5 ); +} + +/*-----------------------------------------------------------------*/ +/* genMinusDec :- does subtraction with deccrement if possible */ +/*-----------------------------------------------------------------*/ +static bool +genMinusDec (iCode * ic) +{ + +return FALSE; +} + +/*-----------------------------------------------------------------*/ +/* genMinus - generates code for subtraction */ +/*-----------------------------------------------------------------*/ +static void +genMinus (iCode * ic) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genMultOneByte : 8 bit multiplication & division */ +/*-----------------------------------------------------------------*/ +static void +genMultOneByte (operand * left, operand * right, operand * result) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genMult - generates code for multiplication */ +/*-----------------------------------------------------------------*/ +static void +genMult (iCode * ic) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genDiv - generates code for division */ +/*-----------------------------------------------------------------*/ +static void +genDiv (iCode * ic) +{ + /* should have been converted to function call */ + assert (0); +} + +/*-----------------------------------------------------------------*/ +/* genMod - generates code for division */ +/*-----------------------------------------------------------------*/ +static void +genMod (iCode * ic) +{ + /* should have been converted to function call */ + assert (0); + +} + +enum { + PBLAZE_EQ = 0, + PBLAZE_NE, + PBLAZE_LT, + PBLAZE_GE +}; + +/*-----------------------------------------------------------------*/ +/* revpblazecnd - reverse a conditional for pblaze */ +/*-----------------------------------------------------------------*/ +static int +revpblazecnd (int type) +{ + static struct { + int type, rtype; + } rar[] = { + { + PBLAZE_EQ, PBLAZE_NE} + , { + PBLAZE_LT, PBLAZE_GE} + }; + int i; + + for (i = 0; i < (sizeof (rar) / sizeof (rar[0])); i++) { + if (rar[i].type == type) + return rar[i].rtype; + if (rar[i].rtype == type) + return rar[i].type; + } + assert (0); /* cannot happen */ + return 0; /* makes the compiler happy */ +} + + +/*-----------------------------------------------------------------*/ +/* genBranch - generate the branch instruction */ +/*-----------------------------------------------------------------*/ +static void +genBranch (iCode * ifx, int br_type, int sign) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genCmp - compare & jump */ +/*-----------------------------------------------------------------*/ +static void +genCmp (iCode * ic, iCode * ifx, int br_type) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genCmpGt :- greater than comparison */ +/*-----------------------------------------------------------------*/ +static void +genCmpGt (iCode * ic, iCode * ifx) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genCmpLt - less than comparisons */ +/*-----------------------------------------------------------------*/ +static void +genCmpLt (iCode * ic, iCode * ifx) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genCmpEq - generates code for equal to */ +/*-----------------------------------------------------------------*/ +static void +genCmpEq (iCode * ic, iCode * ifx) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genCmpNe - generates code for not equal to */ +/*-----------------------------------------------------------------*/ +static void +genCmpNe (iCode * ic, iCode * ifx) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genCmpGe - generates code for greater than equal to */ +/*-----------------------------------------------------------------*/ +static void +genCmpGe (iCode * ic, iCode * ifx) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genCmpLe - generates code for less than equal to */ +/*-----------------------------------------------------------------*/ +static void +genCmpLe (iCode * ic, iCode * ifx) +{ + +} + +/*-----------------------------------------------------------------*/ +/* ifxForOp - returns the icode containing the ifx for operand */ +/*-----------------------------------------------------------------*/ +static iCode * +ifxForOp (operand * op, iCode * ic) +{ + /* if true symbol then needs to be assigned */ + if (IS_TRUE_SYMOP (op)) + return NULL; + + /* if this has register type condition and + the next instruction is ifx with the same operand + and live to of the operand is upto the ifx only then */ + if (ic->next && + ic->next->op == IFX && + IC_COND (ic->next)->key == op->key && + OP_SYMBOL (op)->liveTo <= ic->next->seq) return ic->next; + + return NULL; +} + +/*-----------------------------------------------------------------*/ +/* genAndOp - for && operation */ +/*-----------------------------------------------------------------*/ +static void +genAndOp (iCode * ic) +{ + +} + + +/*-----------------------------------------------------------------*/ +/* genOrOp - for || operation */ +/*-----------------------------------------------------------------*/ +static void +genOrOp (iCode * ic) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genBitWise - generate bitwise operations */ +/*-----------------------------------------------------------------*/ +static void +genBitWise (iCode * ic, iCode * ifx, int bitop) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genAnd - code for and */ +/*-----------------------------------------------------------------*/ +static void +genAnd (iCode * ic, iCode * ifx) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genOr - code for or */ +/*-----------------------------------------------------------------*/ +static void +genOr (iCode * ic, iCode * ifx) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genXor - code for xclusive or */ +/*-----------------------------------------------------------------*/ +static void +genXor (iCode * ic, iCode * ifx) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genInline - write the inline code out */ +/*-----------------------------------------------------------------*/ +static void +genInline (iCode * ic) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genRotC - rotate right/left with carry , lr = 1 rotate right */ +/*-----------------------------------------------------------------*/ +static void +genRotC (iCode * ic, int lr) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genRRC - rotate right with carry */ +/*-----------------------------------------------------------------*/ +static void +genRRC (iCode * ic) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genRLC - generate code for rotate left with carry */ +/*-----------------------------------------------------------------*/ +static void +genRLC (iCode * ic) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genGetHbit - generates code get highest order bit */ +/*-----------------------------------------------------------------*/ +static void +genGetHbit (iCode * ic) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genShiftLeftLit - shift left by a known amount */ +/*-----------------------------------------------------------------*/ +static void +genShiftLeftLit (iCode * ic) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genLeftShift - generates code for left shifting */ +/*-----------------------------------------------------------------*/ +static void +genLeftShift (iCode * ic) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genShiftRightLit - generate for right shift with known count */ +/*-----------------------------------------------------------------*/ +static void +genShiftRightLit (iCode * ic) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genRightShift - generate code for right shifting */ +/*-----------------------------------------------------------------*/ +static void +genRightShift (iCode * ic) +{ + +} + +/*-----------------------------------------------------------------*/ +/* RRsh - shift right rn by known count */ +/*-----------------------------------------------------------------*/ +static void +RRsh (int shCount,int reg) +{ + +} + +/*-----------------------------------------------------------------*/ +/* RLsh - shift left rn by known count */ +/*-----------------------------------------------------------------*/ +static void +RLsh (int shCount, int reg) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genUnpackBits - generates code for unpacking bits */ +/*-----------------------------------------------------------------*/ +static void +genUnpackBits (operand * result, char *rname, int ptype) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genDataPointerGet - generates code when ptr offset is known */ +/*-----------------------------------------------------------------*/ +static void +genDataPointerGet (operand * left, operand * result, iCode * ic) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genNearPointerGet - emitcode for near pointer fetch */ +/*-----------------------------------------------------------------*/ +static void +genMemPointerGet (operand * left, operand * result, iCode * ic, iCode *pi) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genCodePointerGet - gget value from code space */ +/*-----------------------------------------------------------------*/ +static void +genCodePointerGet (operand * left, operand * result, iCode * ic, iCode *pi) +{ + + +} + +/*-----------------------------------------------------------------*/ +/* genPointerGet - generate code for pointer get */ +/*-----------------------------------------------------------------*/ +static void +genPointerGet (iCode * ic, iCode *pi) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genPackBits - generates code for packed bit storage */ +/*-----------------------------------------------------------------*/ +static void +genPackBits (sym_link * etype, + operand * right, + char *rname, int p_type) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genDataPointerSet - remat pointer to data space */ +/*-----------------------------------------------------------------*/ +static void +genDataPointerSet (operand * right, operand * result, iCode * ic) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genNearPointerSet - emitcode for near pointer put */ +/*-----------------------------------------------------------------*/ +static void +genMemPointerSet (operand * right, operand * result, iCode * ic, iCode *pi) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genGenPointerSet - set value from generic pointer space */ +/*-----------------------------------------------------------------*/ +static void +genGenPointerSet (operand * right, operand * result, iCode * ic, iCode *pi) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genPointerSet - stores the value into a pointer location */ +/*-----------------------------------------------------------------*/ +static void +genPointerSet (iCode * ic, iCode *pi) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genIfx - generate code for Ifx statement */ +/*-----------------------------------------------------------------*/ +static void +genIfx (iCode * ic, iCode * popIc) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genAddrOf - generates code for address of */ +/*-----------------------------------------------------------------*/ +static void +genAddrOf (iCode * ic) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genFarFarAssign - assignment when both are in far space */ +/*-----------------------------------------------------------------*/ +static void +genFarFarAssign (operand * result, operand * right, iCode * ic) +{ + + +} + +/*-----------------------------------------------------------------*/ +/* genAssign - generate code for assignment */ +/*-----------------------------------------------------------------*/ +static void +genAssign (iCode * ic) +{ + operand *result, *right; + int size, offset; + unsigned long lit = 0L; + int i; + + D(emitcode (";", "genAssign")); + + result = IC_RESULT (ic); + right = IC_RIGHT (ic); + + + // TODO: all options + /* right side is a literal value */ + if (IS_OP_LITERAL (right)) { + value *aop_lit; + + aop_lit = right->operand.valOperand; + + /* get value and size */ + lit = ulFromVal (aop_lit); + size = getSize ( operandType (right) ); + + + /* left side is a symbol - register */ + if( OP_SYMBOL(result) ) { + + OP_SYMBOL(result)->nRegs = size; + + /* assign registers */ + assignReg (result); + + + for(i = 0; i<size; i++) { + emitcode ("load", "%s, %02x", OP_SYMBOL(result)->regs[i]->name , (unsigned int) ((lit >> (i * 8)) & 0x0FFL) ); + + } + + + } + + // printf("ic:%d\tsize:%d\n",ic->key,size); + + + + } + +} + +/*-----------------------------------------------------------------*/ +/* genJumpTab - genrates code for jump table */ +/*-----------------------------------------------------------------*/ +static void +genJumpTab (iCode * ic) +{ + + +} + +/*-----------------------------------------------------------------*/ +/* genCast - gen code for casting */ +/*-----------------------------------------------------------------*/ +static void +genCast (iCode * ic) +{ + + +} + +/*-----------------------------------------------------------------*/ +/* genReceive - generate code for a receive iCode */ +/*-----------------------------------------------------------------*/ +static void +genReceive (iCode * ic) +{ + +} + +/*-----------------------------------------------------------------*/ +/* genDummyRead - generate code for dummy read of volatiles */ +/*-----------------------------------------------------------------*/ +static void +genDummyRead (iCode * ic) +{ + emitcode ("; genDummyRead",""); + emitcode ("; not implemented",""); + + ic = ic; +} + +/*-----------------------------------------------------------------*/ +/* gen51Code - generate code for 8051 based controllers */ +/*-----------------------------------------------------------------*/ +void +genJSONCode (iCode * lic) +{ + iCode *ic; + int cln = 0; + + + for (ic = lic; ic; ic = ic->next) { + + if( IS_ARITHMETIC_OP(ic) ) { + + operand *left = IC_LEFT (ic); + if( OP_SYMBOL(left) ) { + printf("name:%s\n", left->operand.symOperand->rname ); + } + + } + // printf("oper:%d\n", ic->op); + + if (cln != ic->lineno) { + if (options.debug) { + debugFile->writeCLine (ic); + } + emitcode (";", "%s %d", ic->filename, ic->lineno); + cln = ic->lineno; + } + + /* depending on the operation */ + switch (ic->op) { + case '!': + genNot (ic); + break; + + case '~': + genCpl (ic); + break; + + case UNARYMINUS: + genUminus (ic); + break; + + case IPUSH: + genIpush (ic); + break; + + case IPOP: + genIpop (ic); + break; + + case CALL: + genCall (ic); + break; + + case PCALL: + genPcall (ic); + break; + + case FUNCTION: + genFunction (ic); + break; + + case ENDFUNCTION: + genEndFunction (ic); + break; + + case RETURN: + genRet (ic); + break; + + case LABEL: + genLabel (ic); + break; + + case GOTO: + genGoto (ic); + break; + + case '+': + genPlus (ic); + break; + + case '-': + genMinus (ic); + break; + + case '*': + genMult (ic); + break; + + case '/': + genDiv (ic); + break; + + case '%': + genMod (ic); + break; + + case '>': + genCmpGt (ic, ifxForOp (IC_RESULT (ic), ic)); + break; + + case '<': + genCmpLt (ic, ifxForOp (IC_RESULT (ic), ic)); + break; + + case LE_OP: + genCmpLe (ic, ifxForOp (IC_RESULT (ic), ic)); + break; + + case GE_OP: + genCmpGe (ic, ifxForOp (IC_RESULT (ic), ic)); + break; + + case NE_OP: + genCmpNe (ic, ifxForOp (IC_RESULT (ic), ic)); + break; + + case EQ_OP: + genCmpEq (ic, ifxForOp (IC_RESULT (ic), ic)); + break; + + case AND_OP: + genAndOp (ic); + break; + + case OR_OP: + genOrOp (ic); + break; + + case '^': + genXor (ic, ifxForOp (IC_RESULT (ic), ic)); + break; + + case '|': + genOr (ic, ifxForOp (IC_RESULT (ic), ic)); + break; + + case BITWISEAND: + genAnd (ic, ifxForOp (IC_RESULT (ic), ic)); + break; + + case INLINEASM: + genInline (ic); + break; + + case RRC: + genRRC (ic); + break; + + case RLC: + genRLC (ic); + break; + + case GETHBIT: + genGetHbit (ic); + break; + + case LEFT_OP: + genLeftShift (ic); + break; + + case RIGHT_OP: + genRightShift (ic); + break; + + case '=': + genAssign (ic); + break; + + case IFX: + genIfx (ic, NULL); + break; + + case ADDRESS_OF: + genAddrOf (ic); + break; + + case JUMPTABLE: + genJumpTab (ic); + break; + + case CAST: + genCast (ic); + break; + + case RECEIVE: + genReceive (ic); + break; + + case SEND: + addSet (&_G.sendSet, ic); + break; + + case DUMMY_READ_VOLATILE: + genDummyRead (ic); + break; + + default: + ic = ic; + } + } + + + /* now we are ready to call the + peep hole optimizer + if (!options.nopeep) + peepHole (&lineHead); + + */ + /* now do the actual printing */ + printLine (lineHead, codeOutBuf); + return; +} diff -NaurbB sdcc-src-3.1.0/src/json/gen.h sdcc-src-3.1.0-pblaze/src/json/gen.h --- sdcc-src-3.1.0/src/json/gen.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/gen.h 2011-02-07 20:04:44.000000000 +0100 @@ -0,0 +1,59 @@ +/*------------------------------------------------------------------------- + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ + +#ifndef SDCCGEN_JSON_H +#define SDCCGEN_JSON_H + +enum + { + AOP_LIT = 1, + AOP_REG, AOP_DIR, + AOP_STK,AOP_STR + }; + +/* type asmop : a homogenised type for + all the different spaces an operand can be + in */ +typedef struct asmop + { + + short type; /* can have values + AOP_LIT - operand is a literal value + AOP_REG - must be loaded into a register + AOP_DIR - direct just a name + + */ + short coff; /* current offset */ + short size; /* total size */ + unsigned freed:1; /* already freed */ + union + { + value *aop_lit; /* if literal */ + regs *aop_reg[4]; /* array of registers */ + char *aop_dir; /* if direct */ + } + aopu; + } +asmop; + +void genJSONCode (iCode *); +void json_emitDebuggerSymbol (const char *); + +#endif diff -NaurbB sdcc-src-3.1.0/src/json/json/AUTHORS sdcc-src-3.1.0-pblaze/src/json/json/AUTHORS --- sdcc-src-3.1.0/src/json/json/AUTHORS 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/json/AUTHORS 2011-02-07 20:04:46.000000000 +0100 @@ -0,0 +1,2 @@ +Michael Clark <michael@metaparadigm.com> +C. Watford (christopher.watford@gmail.com) diff -NaurbB sdcc-src-3.1.0/src/json/json/COPYING sdcc-src-3.1.0-pblaze/src/json/json/COPYING --- sdcc-src-3.1.0/src/json/json/COPYING 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/json/COPYING 2011-02-07 20:04:46.000000000 +0100 @@ -0,0 +1,19 @@ +Copyright (c) 2004, 2005 Metaparadigm Pte Ltd + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff -NaurbB sdcc-src-3.1.0/src/json/json/arraylist.c sdcc-src-3.1.0-pblaze/src/json/json/arraylist.c --- sdcc-src-3.1.0/src/json/json/arraylist.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/json/arraylist.c 2011-02-07 20:04:46.000000000 +0100 @@ -0,0 +1,93 @@ +/* + * $Id: arraylist.c,v 1.4 2006/01/26 02:16:28 mclark Exp $ + * + * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. + * Michael Clark <michael@metaparadigm.com> + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See COPYING for details. + * + */ + +#include "config.h" + +#if STDC_HEADERS +# include <stdlib.h> +# include <string.h> +#endif /* STDC_HEADERS */ + +#if HAVE_STRINGS_H +# include <strings.h> +#endif /* HAVE_STRINGS_H */ + +#include "bits.h" +#include "arraylist.h" + +struct array_list* +array_list_new(array_list_free_fn *free_fn) +{ + struct array_list *this; + + if(!(this = calloc(1, sizeof(struct array_list)))) return NULL; + this->size = ARRAY_LIST_DEFAULT_SIZE; + this->length = 0; + this->free_fn = free_fn; + if(!(this->array = calloc(sizeof(void*), this->size))) { + free(this); + return NULL; + } + return this; +} + +extern void +array_list_free(struct array_list *this) +{ + int i; + for(i = 0; i < this->length; i++) + if(this->array[i]) this->free_fn(this->array[i]); + free(this->array); + free(this); +} + +void* +array_list_get_idx(struct array_list *this, int i) +{ + if(i >= this->length) return NULL; + return this->array[i]; +} + +static int array_list_expand_internal(struct array_list *this, int max) +{ + void *t; + int new_size; + + if(max < this->size) return 0; + new_size = max(this->size << 1, max); + if(!(t = realloc(this->array, new_size*sizeof(void*)))) return -1; + this->array = t; + (void)memset(this->array + this->size, 0, (new_size-this->size)*sizeof(void*)); + this->size = new_size; + return 0; +} + +int +array_list_put_idx(struct array_list *this, int idx, void *data) +{ + if(array_list_expand_internal(this, idx)) return -1; + if(this->array[idx]) this->free_fn(this->array[idx]); + this->array[idx] = data; + if(this->length <= idx) this->length = idx + 1; + return 0; +} + +int +array_list_add(struct array_list *this, void *data) +{ + return array_list_put_idx(this, this->length, data); +} + +int +array_list_length(struct array_list *this) +{ + return this->length; +} diff -NaurbB sdcc-src-3.1.0/src/json/json/arraylist.h sdcc-src-3.1.0-pblaze/src/json/json/arraylist.h --- sdcc-src-3.1.0/src/json/json/arraylist.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/json/arraylist.h 2011-02-07 20:04:46.000000000 +0100 @@ -0,0 +1,45 @@ +/* + * $Id: arraylist.h,v 1.4 2006/01/26 02:16:28 mclark Exp $ + * + * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. + * Michael Clark <michael@metaparadigm.com> + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See COPYING for details. + * + */ + +#ifndef _arraylist_h_ +#define _arraylist_h_ + +#define ARRAY_LIST_DEFAULT_SIZE 32 + +typedef void (array_list_free_fn) (void *data); + +struct array_list +{ + void **array; + int length; + int size; + array_list_free_fn *free_fn; +}; + +extern struct array_list* +array_list_new(array_list_free_fn *free_fn); + +extern void +array_list_free(struct array_list *al); + +extern void* +array_list_get_idx(struct array_list *al, int i); + +extern int +array_list_put_idx(struct array_list *al, int i, void *data); + +extern int +array_list_add(struct array_list *al, void *data); + +extern int +array_list_length(struct array_list *al); + +#endif diff -NaurbB sdcc-src-3.1.0/src/json/json/bits.h sdcc-src-3.1.0-pblaze/src/json/json/bits.h --- sdcc-src-3.1.0/src/json/json/bits.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/json/bits.h 2011-02-07 20:04:46.000000000 +0100 @@ -0,0 +1,27 @@ +/* + * $Id: bits.h,v 1.10 2006/01/30 23:07:57 mclark Exp $ + * + * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. + * Michael Clark <michael@metaparadigm.com> + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See COPYING for details. + * + */ + +#ifndef _bits_h_ +#define _bits_h_ + +#ifndef min +//#define min(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef max +//#define max(a,b) ((a) > (b) ? (a) : (b)) +#endif + +#define hexdigit(x) (((x) <= '9') ? (x) - '0' : ((x) & 7) + 9) +#define error_ptr(error) ((void*)error) +#define is_error(ptr) ((unsigned long)ptr > (unsigned long)-4000L) + +#endif diff -NaurbB sdcc-src-3.1.0/src/json/json/config.h sdcc-src-3.1.0-pblaze/src/json/json/config.h --- sdcc-src-3.1.0/src/json/json/config.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/json/config.h 2011-02-07 20:04:46.000000000 +0100 @@ -0,0 +1,94 @@ +/* + * $Id: config.h.win32,v 1.2 2006/01/26 02:16:28 mclark Exp $ + * + * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. + * Michael Clark <michael@metaparadigm.com> + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See COPYING for details. + * + */ + +/* config.h.win32 Generated by configure. */ + +#define PACKAGE_STRING "JSON C Library 0.2" +#define PACKAGE_BUGREPORT "michael@metaparadigm.com" +#define PACKAGE_NAME "JSON C Library" +#define PACKAGE_TARNAME "json-c" +#define PACKAGE_VERSION "0.2" + +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ +/* #undef HAVE_DOPRNT */ + +/* Define to 1 if you have the <fcntl.h> header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the <inttypes.h> header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the <limits.h> header file. */ +#define HAVE_LIMITS_H 1 + +/* Define to 1 if your system has a GNU libc compatible `malloc' function, and + to 0 otherwise. */ +#define HAVE_MALLOC 1 + +/* Define to 1 if you have the <memory.h> header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `open' function. */ +#undef HAVE_OPEN + +/* Define to 1 if your system has a GNU libc compatible `realloc' function, + and to 0 otherwise. */ +#define HAVE_REALLOC 1 + +/* Define to 1 if you have the <stdint.h> header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the <stdlib.h> header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRNDUP + +/* Define to 1 if you have the <stdarg.h> header file. */ +#define HAVE_STDARG_H 1 + +/* Define to 1 if you have the `strerror' function. */ +#define HAVE_STRERROR 1 + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the <syslog.h> header file. */ +#undef HAVE_SYSLOG_H + +/* Define to 1 if you have the <sys/param.h> header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the <sys/types.h> header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vprintf' function. */ +#undef HAVE_VPRINTF + +/* Define to 1 if you have the `vsyslog' function. */ +#undef HAVE_VSYSLOG + +/* Define to 1 if you have the `strncasecmp' function. */ +#undef HAVE_STRNCASECMP + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 diff -NaurbB sdcc-src-3.1.0/src/json/json/debug.c sdcc-src-3.1.0-pblaze/src/json/json/debug.c --- sdcc-src-3.1.0/src/json/json/debug.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/json/debug.c 2011-02-07 20:04:46.000000000 +0100 @@ -0,0 +1,98 @@ +/* + * $Id: debug.c,v 1.5 2006/01/26 02:16:28 mclark Exp $ + * + * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. + * Michael Clark <michael@metaparadigm.com> + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See COPYING for details. + * + */ + +#include "config.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> + +#if HAVE_SYSLOG_H +# include <syslog.h> +#endif /* HAVE_SYSLOG_H */ + +#if HAVE_UNISTD_H +# include <unistd.h> +#endif /* HAVE_UNISTD_H */ + +#if HAVE_SYS_PARAM_H +#include <sys/param.h> +#endif /* HAVE_SYS_PARAM_H */ + +#include "debug.h" + +static int _syslog = 0; +static int _debug = 0; + +void mc_set_debug(int debug) { _debug = debug; } +int mc_get_debug() { return _debug; } + +extern void mc_set_syslog(int syslog) +{ + _syslog = syslog; +} + +void mc_abort(const char *msg, ...) +{ + va_list ap; + va_start(ap, msg); +#if HAVE_VSYSLOG + if(_syslog) { + vsyslog(LOG_ERR, msg, ap); + } else +#endif + vprintf(msg, ap); + va_end(ap); + exit(1); +} + + +void mc_debug(const char *msg, ...) +{ + va_list ap; + if(_debug) { + va_start(ap, msg); +#if HAVE_VSYSLOG + if(_syslog) { + vsyslog(LOG_DEBUG, msg, ap); + } else +#endif + vprintf(msg, ap); + va_end(ap); + } +} + +void mc_error(const char *msg, ...) +{ + va_list ap; + va_start(ap, msg); +#if HAVE_VSYSLOG + if(_syslog) { + vsyslog(LOG_ERR, msg, ap); + } else +#endif + vfprintf(stderr, msg, ap); + va_end(ap); +} + +void mc_info(const char *msg, ...) +{ + va_list ap; + va_start(ap, msg); +#if HAVE_VSYSLOG + if(_syslog) { + vsyslog(LOG_INFO, msg, ap); + } else +#endif + vfprintf(stderr, msg, ap); + va_end(ap); +} diff -NaurbB sdcc-src-3.1.0/src/json/json/debug.h sdcc-src-3.1.0-pblaze/src/json/json/debug.h --- sdcc-src-3.1.0/src/json/json/debug.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/json/debug.h 2011-02-07 20:04:46.000000000 +0100 @@ -0,0 +1,42 @@ +/* + * $Id: debug.h,v 1.5 2006/01/30 23:07:57 mclark Exp $ + * + * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. + * Michael Clark <michael@metaparadigm.com> + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See COPYING for details. + * + */ + +#ifndef _DEBUG_H_ +#define _DEBUG_H_ + +extern void mc_set_debug(int debug); +extern int mc_get_debug(void); + +extern void mc_set_syslog(int syslog); +extern void mc_abort(const char *msg, ...); +extern void mc_debug(const char *msg, ...); +extern void mc_error(const char *msg, ...); +extern void mc_info(const char *msg, ...); + +#ifdef MC_MAINTAINER_MODE +#define MC_SET_DEBUG(x) mc_set_debug(x) +#define MC_GET_DEBUG() mc_get_debug() +#define MC_SET_SYSLOG(x) mc_set_syslog(x) +#define MC_ABORT(x, ...) mc_abort(x, ##__VA_ARGS__) +#define MC_DEBUG(x, ...) mc_debug(x, ##__VA_ARGS__) +#define MC_ERROR(x, ...) mc_error(x, ##__VA_ARGS__) +#define MC_INFO(x, ...) mc_info(x, ##__VA_ARGS__) +#else +#define MC_SET_DEBUG(x) if (0) mc_set_debug(x) +#define MC_GET_DEBUG() (0) +#define MC_SET_SYSLOG(x) if (0) mc_set_syslog(x) +#define MC_ABORT(x, ...) if (0) mc_abort(x, ##__VA_ARGS__) +#define MC_DEBUG(x, ...) if (0) mc_debug(x, ##__VA_ARGS__) +#define MC_ERROR(x, ...) if (0) mc_error(x, ##__VA_ARGS__) +#define MC_INFO(x, ...) if (0) mc_info(x, ##__VA_ARGS__) +#endif + +#endif diff -NaurbB sdcc-src-3.1.0/src/json/json/json.h sdcc-src-3.1.0-pblaze/src/json/json/json.h --- sdcc-src-3.1.0/src/json/json/json.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/json/json.h 2011-02-07 20:04:46.000000000 +0100 @@ -0,0 +1,31 @@ +/* + * $Id: json.h,v 1.6 2006/01/26 02:16:28 mclark Exp $ + * + * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. + * Michael Clark <michael@metaparadigm.com> + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See COPYING for details. + * + */ + +#ifndef _json_h_ +#define _json_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "bits.h" +#include "debug.h" +#include "linkhash.h" +#include "arraylist.h" +#include "json_util.h" +#include "json_object.h" +#include "json_tokener.h" + +#ifdef __cplusplus +} +#endif + +#endif diff -NaurbB sdcc-src-3.1.0/src/json/json/json_object.c sdcc-src-3.1.0-pblaze/src/json/json/json_object.c --- sdcc-src-3.1.0/src/json/json/json_object.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/json/json_object.c 2011-02-07 20:04:46.000000000 +0100 @@ -0,0 +1,569 @@ +/* + * $Id: json_object.c,v 1.17 2006/07/25 03:24:50 mclark Exp $ + * + * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. + * Michael Clark <michael@metaparadigm.com> + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See COPYING for details. + * + */ + +#include "config.h" + +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <string.h> + +#include "debug.h" +#include "printbuf.h" +#include "linkhash.h" +#include "arraylist.h" +#include "json_object.h" +#include "json_object_private.h" +#include "json_tokener.h" + +#include "SDCCglobl.h" + +#if !HAVE_STRNDUP + char* strndup(const char* str, size_t n); +#endif /* !HAVE_STRNDUP */ + +#define REFCOUNT_DEBUG 1 + +const char *json_number_chars = "0123456789.+-eE"; +const char *json_hex_chars = "0123456789abcdef"; +int indent = TRUE; // indent enable +int indentDeep = 0; // contain actual deep during the string generation +int indentStep = 4; // one tabulator equals to 4 spaces +int carRet = FALSE; // insert the return character in front of the opening bracket { or [ ? + +#ifdef REFCOUNT_DEBUG +static const char* json_type_name[] = { + "null", + "boolean", + "double", + "int", + "object", + "array", + "string", +}; +#endif /* REFCOUNT_DEBUG */ + +static void json_object_generic_delete(struct json_object* this); +static struct json_object* json_object_new(enum json_type o_type); + + +/* ref count debugging */ + +#ifdef REFCOUNT_DEBUG + +static struct lh_table *json_object_table; + +//static void json_object_init(void) __attribute__ ((constructor)); +/*extern*/ static void json_object_init(void) { + MC_DEBUG("json_object_init: creating object table\n"); + json_object_table = lh_kptr_table_new(128, "json_object_table", NULL); +} + +//static void json_object_fini(void) __attribute__ ((destructor)); +/*extern*/ static void json_object_fini(void) { + struct lh_entry *ent; + if(MC_GET_DEBUG()) { + if (json_object_table->count) { + MC_DEBUG("json_object_fini: %d referenced objects at exit\n", + json_object_table->count); + lh_foreach(json_object_table, ent) { + struct json_object* obj = (struct json_object*)ent->v; + MC_DEBUG("\t%s:%p\n", json_type_name[obj->o_type], obj); + } + } + } + MC_DEBUG("json_object_fini: freeing object table\n"); + lh_table_free(json_object_table); +} +#endif /* REFCOUNT_DEBUG */ + + +/* string escaping */ + +static int json_escape_str(struct printbuf *pb, char *str) +{ + int pos = 0, start_offset = 0; + unsigned char c; + do { + c = str[pos]; + switch(c) { + case '\0': + break; + case '\b': + case '\n': + case '\r': + case '\t': + case '"': + case '\\': + case '/': + if(pos - start_offset > 0) + printbuf_memappend(pb, str + start_offset, pos - start_offset); + if(c == '\b') printbuf_memappend(pb, "\\b", 2); + else if(c == '\n') printbuf_memappend(pb, "\\n", 2); + else if(c == '\r') printbuf_memappend(pb, "\\r", 2); + else if(c == '\t') printbuf_memappend(pb, "\\t", 2); + else if(c == '"') printbuf_memappend(pb, "\\\"", 2); + else if(c == '\\') printbuf_memappend(pb, "\\\\", 2); + else if(c == '/') printbuf_memappend(pb, "\\/", 2); + start_offset = ++pos; + break; + default: + if(c < ' ') { + if(pos - start_offset > 0) + printbuf_memappend(pb, str + start_offset, pos - start_offset); + sprintbuf(pb, "\\u00%c%c", + json_hex_chars[c >> 4], + json_hex_chars[c & 0xf]); + start_offset = ++pos; + } else pos++; + } + } while(c); + if(pos - start_offset > 0) + printbuf_memappend(pb, str + start_offset, pos - start_offset); + return 0; +} + + +/* reference counting */ + +extern struct json_object* json_object_get(struct json_object *this) +{ + if(this) { + this->_ref_count++; + } + return this; +} + +extern void json_object_put(struct json_object *this) +{ + if(this) { + this->_ref_count--; + if(!this->_ref_count) this->_delete(this); + } +} + + +/* generic object construction and destruction parts */ + +static void json_object_generic_delete(struct json_object* this) +{ +#ifdef REFCOUNT_DEBUG + MC_DEBUG("json_object_delete_%s: %p\n", + json_type_name[this->o_type], this); + lh_table_delete(json_object_table, this); +#endif /* REFCOUNT_DEBUG */ + printbuf_free(this->_pb); + free(this); +} + +static struct json_object* json_object_new(enum json_type o_type) +{ + struct json_object *this = calloc(sizeof(struct json_object), 1); + if(!this) return NULL; + this->o_type = o_type; + this->_ref_count = 1; + this->_delete = &json_object_generic_delete; +#ifdef REFCOUNT_DEBUG + if (json_object_table == NULL) + json_object_table = lh_kptr_table_new(128, "json_object_table", NULL); + lh_table_insert(json_object_table, this, this); + MC_DEBUG("json_object_new_%s: %p\n", json_type_name[this->o_type], this); +#endif /* REFCOUNT_DEBUG */ + return this; +} + + +/* type checking functions */ + +int json_object_is_type(struct json_object *this, enum json_type type) +{ + return (this->o_type == type); +} + +enum json_type json_object_get_type(struct json_object *this) +{ + return this->o_type; +} + + +/* json_object_to_json_string */ + +const char* json_object_to_json_string(struct json_object *this) +{ + if(!this) return "null"; + if(!this->_pb) { + if(!(this->_pb = printbuf_new())) return NULL; + } else { + printbuf_reset(this->_pb); + } + if(this->_to_json_string(this, this->_pb) < 0) return NULL; + return this->_pb->buf; +} + + +/* json_object_object */ + +static int json_object_object_to_json_string(struct json_object* this, + struct printbuf *pb) +{ + int i=0, j=0; + struct json_object_iter iter; + + if(indent) + { + // sprintbuf(pb, "\n"); + // for(j=0;j<indentStep*indentDeep;j++) + //sprintbuf(pb, " "); + } + sprintbuf(pb, "{"); + + indentDeep++; + + /* CAW: scope operator to make ANSI correctness */ + /* CAW: switched to json_object_object_foreachC which uses an iterator struct */ + json_object_object_foreachC(this, iter) { + if(i) sprintbuf(pb, ","); + if(indent) sprintbuf(pb, "\n"); + if(indent) + for(j=0;j<indentStep*indentDeep-1;j++) + sprintbuf(pb, " "); + sprintbuf(pb, " \""); + json_escape_str(pb, iter.key); + sprintbuf(pb, "\": "); + if(iter.val == NULL) sprintbuf(pb, "null"); + else + { + iter.val->_to_json_string(iter.val, pb); + //if (json_object_get_type(iter.val) == json_type_object) + //{ + + //} + //else if (json_object_get_type(iter.val) == json_type_array) + //{ + + //} + } + i++; + } + + indentDeep--; + if(indent) + { + sprintbuf(pb, "\n"); + for(j=0;j<indentStep*indentDeep;j++) + sprintbuf(pb, " "); + } + else + { + sprintbuf(pb, " "); + } + return sprintbuf(pb, "}"); +} + +static void json_object_lh_entry_free(struct lh_entry *ent) +{ + free(ent->k); + json_object_put((struct json_object*)ent->v); +} + +static void json_object_object_delete(struct json_object* this) +{ + lh_table_free(this->o.c_object); + json_object_generic_delete(this); +} + +struct json_object* json_object_new_object() +{ + struct json_object *this = json_object_new(json_type_object); + if(!this) return NULL; + this->_delete = &json_object_object_delete; + this->_to_json_string = &json_object_object_to_json_string; + this->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTIRES, + NULL, &json_object_lh_entry_free); + return this; +} + +struct lh_table* json_object_get_object(struct json_object *this) +{ + if(!this) return NULL; + switch(this->o_type) { + case json_type_object: + return this->o.c_object; + default: + return NULL; + } +} + +void json_object_object_add(struct json_object* this, const char *key, + struct json_object *val) +{ + lh_table_delete(this->o.c_object, key); + lh_table_insert(this->o.c_object, strdup(key), val); +} + +struct json_object* json_object_object_get(struct json_object* this, const char *key) +{ + return (struct json_object*) lh_table_lookup(this->o.c_object, key); +} + +void json_object_object_del(struct json_object* this, const char *key) +{ + lh_table_delete(this->o.c_object, key); +} + + +/* json_object_boolean */ + +static int json_object_boolean_to_json_string(struct json_object* this, + struct printbuf *pb) +{ + if(this->o.c_boolean) return sprintbuf(pb, "true"); + else return sprintbuf(pb, "false"); +} + +struct json_object* json_object_new_boolean(boolean b) +{ + struct json_object *this = json_object_new(json_type_boolean); + if(!this) return NULL; + this->_to_json_string = &json_object_boolean_to_json_string; + this->o.c_boolean = b; + return this; +} + +boolean json_object_get_boolean(struct json_object *this) +{ + if(!this) return FALSE; + switch(this->o_type) { + case json_type_boolean: + return this->o.c_boolean; + case json_type_int: + return (this->o.c_int != 0); + case json_type_double: + return (this->o.c_double != 0); + case json_type_string: + if(strlen(this->o.c_string)) return TRUE; + default: + return TRUE; + } +} + + +/* json_object_int */ + +static int json_object_int_to_json_string(struct json_object* this, + struct printbuf *pb) +{ + return sprintbuf(pb, "%d", this->o.c_int); +} + +struct json_object* json_object_new_int(int i) +{ + struct json_object *this = json_object_new(json_type_int); + if(!this) return NULL; + this->_to_json_string = &json_object_int_to_json_string; + this->o.c_int = i; + return this; +} + +int json_object_get_int(struct json_object *this) +{ + int cint; + + if(!this) return 0; + switch(this->o_type) { + case json_type_int: + return this->o.c_int; + case json_type_double: + return (int)this->o.c_double; + case json_type_boolean: + return this->o.c_boolean; + case json_type_string: + if(sscanf(this->o.c_string, "%d", &cint) == 1) return cint; + default: + return 0; + } +} + + +/* json_object_double */ + +static int json_object_double_to_json_string(struct json_object* this, + struct printbuf *pb) +{ + return sprintbuf(pb, "%lf", this->o.c_double); +} + +struct json_object* json_object_new_double(double d) +{ + struct json_object *this = json_object_new(json_type_double); + if(!this) return NULL; + this->_to_json_string = &json_object_double_to_json_string; + this->o.c_double = d; + return this; +} + +double json_object_get_double(struct json_object *this) +{ + double cdouble; + + if(!this) return 0.0; + switch(this->o_type) { + case json_type_double: + return this->o.c_double; + case json_type_int: + return this->o.c_int; + case json_type_boolean: + return this->o.c_boolean; + case json_type_string: + if(sscanf(this->o.c_string, "%lf", &cdouble) == 1) return cdouble; + default: + return 0.0; + } +} + + +/* json_object_string */ + +static int json_object_string_to_json_string(struct json_object* this, + struct printbuf *pb) +{ + sprintbuf(pb, "\""); + json_escape_str(pb, this->o.c_string); + sprintbuf(pb, "\""); + return 0; +} + +static void json_object_string_delete(struct json_object* this) +{ + free(this->o.c_string); + json_object_generic_delete(this); +} + +struct json_object* json_object_new_string(const char *s) +{ + struct json_object *this = json_object_new(json_type_string); + if(!this) return NULL; + this->_delete = &json_object_string_delete; + this->_to_json_string = &json_object_string_to_json_string; + this->o.c_string = strdup(s); + return this; +} + +struct json_object* json_object_new_string_len(const char *s, int len) +{ + struct json_object *this = json_object_new(json_type_string); + if(!this) return NULL; + this->_delete = &json_object_string_delete; + this->_to_json_string = &json_object_string_to_json_string; + this->o.c_string = strndup(s, len); + return this; +} + +const char* json_object_get_string(struct json_object *this) +{ + if(!this) return NULL; + switch(this->o_type) { + case json_type_string: + return this->o.c_string; + default: + return json_object_to_json_string(this); + } +} + + +/* json_object_array */ + +static int json_object_array_to_json_string(struct json_object* this, + struct printbuf *pb) +{ + int i,j; + sprintbuf(pb, "["); + indentDeep++; + for(i=0; i < json_object_array_length(this); i++) { + struct json_object *val; + if(i) { sprintbuf(pb, ", "); } + else { sprintbuf(pb, " "); } + if(indent) + { + sprintbuf(pb, "\n"); + for(j=0;j<indentDeep*indentStep;j++) + sprintbuf(pb, " "); + } + val = json_object_array_get_idx(this, i); + if(val == NULL) { sprintbuf(pb, "null"); } + else { val->_to_json_string(val, pb); } + } + indentDeep--; + if(indent) + { + sprintbuf(pb, "\n"); + for(j=0;j<indentDeep*indentStep;j++) + sprintbuf(pb, " "); + } + else + sprintbuf(pb, " "); + return sprintbuf(pb, "]"); +} + +static void json_object_array_entry_free(void *data) +{ + json_object_put((struct json_object*)data); +} + +static void json_object_array_delete(struct json_object* this) +{ + array_list_free(this->o.c_array); + json_object_generic_delete(this); +} + +struct json_object* json_object_new_array() +{ + struct json_object *this = json_object_new(json_type_array); + if(!this) return NULL; + this->_delete = &json_object_array_delete; + this->_to_json_string = &json_object_array_to_json_string; + this->o.c_array = array_list_new(&json_object_array_entry_free); + return this; +} + +struct array_list* json_object_get_array(struct json_object *this) +{ + if(!this) return NULL; + switch(this->o_type) { + case json_type_array: + return this->o.c_array; + default: + return NULL; + } +} + +int json_object_array_length(struct json_object *this) +{ + return array_list_length(this->o.c_array); +} + +int json_object_array_add(struct json_object *this,struct json_object *val) +{ + return array_list_add(this->o.c_array, val); +} + +int json_object_array_put_idx(struct json_object *this, int idx, + struct json_object *val) +{ + return array_list_put_idx(this->o.c_array, idx, val); +} + +struct json_object* json_object_array_get_idx(struct json_object *this, + int idx) +{ + return (struct json_object*)array_list_get_idx(this->o.c_array, idx); +} + diff -NaurbB sdcc-src-3.1.0/src/json/json/json_object.h sdcc-src-3.1.0-pblaze/src/json/json/json_object.h --- sdcc-src-3.1.0/src/json/json/json_object.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/json/json_object.h 2011-02-07 20:04:46.000000000 +0100 @@ -0,0 +1,316 @@ +/* + * $Id: json_object.h,v 1.12 2006/01/30 23:07:57 mclark Exp $ + * + * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. + * Michael Clark <michael@metaparadigm.com> + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See COPYING for details. + * + */ + +#ifndef _json_object_h_ +#define _json_object_h_ + +#define JSON_OBJECT_DEF_HASH_ENTIRES 16 + +//#undef FALSE +//#define FALSE ((boolean)0) + +//#undef TRUE +//#define TRUE ((boolean)1) + +extern const char *json_number_chars; +extern const char *json_hex_chars; +extern int indent; +extern int indentDeep; +extern int indentStep; + +/* forward structure definitions */ + +typedef int boolean; +struct printbuf; +struct lh_table; +struct array_list; +struct json_object; +struct json_object_iter; + +/* supported object types */ + +enum json_type { + json_type_null, + json_type_boolean, + json_type_double, + json_type_int, + json_type_object, + json_type_array, + json_type_string +}; + +//static void json_object_init(void); +//static void json_object_fini(void); + +/* reference counting functions */ + +/** + * Increment the reference count of json_object + * @param obj the json_object instance + */ +extern struct json_object* json_object_get(struct json_object *obj); + +/** + * Decrement the reference count of json_object and free if it reaches zero + * @param obj the json_object instance + */ +extern void json_object_put(struct json_object *obj); + + +/** + * Check if the json_object is of a given type + * @param obj the json_object instance + * @param type one of: + json_type_boolean, + json_type_double, + json_type_int, + json_type_object, + json_type_array, + json_type_string, + */ +extern int json_object_is_type(struct json_object *obj, enum json_type type); + +/** + * Get the type of the json_object + * @param obj the json_object instance + * @returns type being one of: + json_type_boolean, + json_type_double, + json_type_int, + json_type_object, + json_type_array, + json_type_string, + */ +extern enum json_type json_object_get_type(struct json_object *obj); + + +/** Stringify object to json format + * @param obj the json_object instance + * @returns a string in JSON format + */ +extern const char* json_object_to_json_string(struct json_object *obj); + + +/* object type methods */ + +/** Create a new empty object + * @returns a json_object of type json_type_object + */ +extern struct json_object* json_object_new_object(void); + +/** Get the hashtable of a json_object of type json_type_object + * @param obj the json_object instance + * @returns a linkhash + */ +extern struct lh_table* json_object_get_object(struct json_object *obj); + +/** Add an object field to a json_object of type json_type_object + * + * The reference count will *not* be incremented. This is to make adding + * fields to objects in code more compact. If you want to retain a reference + * to an added object you must wrap the passed object with json_object_get + * + * @param obj the json_object instance + * @param key the object field name (a private copy will be duplicated) + * @param val a json_object or NULL member to associate with the given field + */ +extern void json_object_object_add(struct json_object* obj, const char *key, + struct json_object *val); + +/** Get the json_object associate with a given object field + * @param obj the json_object instance + * @param key the object field name + * @returns the json_object associated with the given field name + */ +extern struct json_object* json_object_object_get(struct json_object* obj, + const char *key); + +/** Delete the given json_object field + * + * The reference count will be decremented for the deleted object + * + * @param obj the json_object instance + * @param key the object field name + */ +extern void json_object_object_del(struct json_object* obj, const char *key); + +/** Iterate through all keys and values of an object + * @param obj the json_object instance + * @param key the local name for the char* key variable defined in the body + * @param val the local name for the json_object* object variable defined in the body + */ +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) + +# define json_object_object_foreach(obj,key,val) \ + char *key; struct json_object *val; \ + for(struct lh_entry *entry = json_object_get_object(obj)->head; ({ if(entry) { key = (char*)entry->k; val = (struct json_object*)entry->v; } ; entry; }); entry = entry->next ) + +#else /* ANSI C or MSC */ + +#define json_object_object_foreach(obj,key,val) \ + char *key; struct json_object *val; struct lh_entry *entry; \ + for(entry = json_object_get_object(obj)->head; (entry ? (key = (char*)entry->k, val = (struct json_object*)entry->v, entry) : 0); entry = entry->next) + +#endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) */ + +/** Iterate through all keys and values of an object (ANSI C Safe) + * @param obj the json_object instance + * @param iter the object iterator + */ +#define json_object_object_foreachC(obj,iter) \ + for(iter.entry = json_object_get_object(obj)->head; (iter.entry ? (iter.key = (char*)iter.entry->k, iter.val = (struct json_object*)iter.entry->v, iter.entry) : 0); iter.entry = iter.entry->next) + +/* Array type methods */ + +/** Create a new empty json_object of type json_type_array + * @returns a json_object of type json_type_array + */ +extern struct json_object* json_object_new_array(void); + +/** Get the arraylist of a json_object of type json_type_array + * @param obj the json_object instance + * @returns an arraylist + */ +extern struct array_list* json_object_get_array(struct json_object *obj); + +/** Get the length of a json_object of type json_type_array + * @param obj the json_object instance + * @returns an int + */ +extern int json_object_array_length(struct json_object *obj); + +/** Add an element to the end of a json_object of type json_type_array + * + * The reference count will *not* be incremented. This is to make adding + * fields to objects in code more compact. If you want to retain a reference + * to an added object you must wrap the passed object with json_object_get + * + * @param obj the json_object instance + * @param val the json_object to be added + */ +extern int json_object_array_add(struct json_object *obj, + struct json_object *val); + +/** Insert or replace an element at a specified index in an array (a json_object of type json_type_array) + * + * The reference count will *not* be incremented. This is to make adding + * fields to objects in code more compact. If you want to retain a reference + * to an added object you must wrap the passed object with json_object_get + * + * The reference count of a replaced object will be decremented. + * + * The array size will be automatically be expanded to the size of the + * index if the index is larger than the current size. + * + * @param obj the json_object instance + * @param idx the index to insert the element at + * @param val the json_object to be added + */ +extern int json_object_array_put_idx(struct json_object *obj, int idx, + struct json_object *val); + +/** Get the element at specificed index of the array (a json_object of type json_type_array) + * @param obj the json_object instance + * @param idx the index to get the element at + * @returns the json_object at the specified index (or NULL) + */ +extern struct json_object* json_object_array_get_idx(struct json_object *obj, + int idx); + +/* boolean type methods */ + +/** Create a new empty json_object of type json_type_boolean + * @param b a boolean TRUE or FALSE (0 or 1) + * @returns a json_object of type json_type_boolean + */ +extern struct json_object* json_object_new_boolean(boolean b); + +/** Get the boolean value of a json_object + * + * The type is coerced to a boolean if the passed object is not a boolean. + * integer and double objects will return FALSE if there value is zero + * or TRUE otherwise. If the passed object is a string it will return + * TRUE if it has a non zero length. If any other object type is passed + * TRUE will be returned if the object is not NULL. + * + * @param obj the json_object instance + * @returns a boolean + */ +extern boolean json_object_get_boolean(struct json_object *obj); + + +/* int type methods */ + +/** Create a new empty json_object of type json_type_int + * @param i the integer + * @returns a json_object of type json_type_int + */ +extern struct json_object* json_object_new_int(int i); + +/** Get the int value of a json_object + * + * The type is coerced to a int if the passed object is not a int. + * double objects will return their integer conversion. Strings will be + * parsed as an integer. If no conversion exists then 0 is returned. + * + * @param obj the json_object instance + * @returns an int + */ +extern int json_object_get_int(struct json_object *obj); + + +/* double type methods */ + +/** Create a new empty json_object of type json_type_double + * @param d the double + * @returns a json_object of type json_type_double + */ +extern struct json_object* json_object_new_double(double d); + +/** Get the double value of a json_object + * + * The type is coerced to a double if the passed object is not a double. + * integer objects will return their dboule conversion. Strings will be + * parsed as a double. If no conversion exists then 0.0 is returned. + * + * @param obj the json_object instance + * @returns an double + */ +extern double json_object_get_double(struct json_object *obj); + + +/* string type methods */ + +/** Create a new empty json_object of type json_type_string + * + * A copy of the string is made and the memory is managed by the json_object + * + * @param s the string + * @returns a json_object of type json_type_string + */ +extern struct json_object* json_object_new_string(const char *s); + +extern struct json_object* json_object_new_string_len(const char *s, int len); + +/** Get the string value of a json_object + * + * If the passed object is not of type json_type_string then the JSON + * representation of the object is returned. + * + * The returned string memory is managed by the json_object and will + * be freed when the reference count of the json_object drops to zero. + * + * @param obj the json_object instance + * @returns a string + */ +extern const char* json_object_get_string(struct json_object *obj); + +#endif diff -NaurbB sdcc-src-3.1.0/src/json/json/json_object_private.h sdcc-src-3.1.0-pblaze/src/json/json/json_object_private.h --- sdcc-src-3.1.0/src/json/json/json_object_private.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/json/json_object_private.h 2011-02-07 20:04:44.000000000 +0100 @@ -0,0 +1,44 @@ +/* + * $Id: json_object_private.h,v 1.4 2006/01/26 02:16:28 mclark Exp $ + * + * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. + * Michael Clark <michael@metaparadigm.com> + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See COPYING for details. + * + */ + +#ifndef _json_object_private_h_ +#define _json_object_private_h_ + +typedef void (json_object_delete_fn)(struct json_object *o); +typedef int (json_object_to_json_string_fn)(struct json_object *o, + struct printbuf *pb); + +struct json_object +{ + enum json_type o_type; + json_object_delete_fn *_delete; + json_object_to_json_string_fn *_to_json_string; + int _ref_count; + struct printbuf *_pb; + union data { + boolean c_boolean; + double c_double; + int c_int; + struct lh_table *c_object; + struct array_list *c_array; + char *c_string; + } o; +}; + +/* CAW: added for ANSI C iteration correctness */ +struct json_object_iter +{ + char *key; + struct json_object *val; + struct lh_entry *entry; +}; + +#endif diff -NaurbB sdcc-src-3.1.0/src/json/json/json_tokener.c sdcc-src-3.1.0-pblaze/src/json/json/json_tokener.c --- sdcc-src-3.1.0/src/json/json/json_tokener.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/json/json_tokener.c 2011-02-07 20:04:46.000000000 +0100 @@ -0,0 +1,517 @@ +/* + * $Id: json_tokener.c,v 1.20 2006/07/25 03:24:50 mclark Exp $ + * + * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. + * Michael Clark <michael@metaparadigm.com> + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See COPYING for details. + * + */ + +#include "config.h" + +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <ctype.h> +#include <string.h> + +#include "bits.h" +#include "debug.h" +#include "printbuf.h" +#include "arraylist.h" +#include "json_object.h" +#include "json_tokener.h" + + +#if !HAVE_STRNCASECMP && defined(_MSC_VER) + /* MSC has the version as _strnicmp */ +# define strncasecmp _strnicmp +#elif !HAVE_STRNCASECMP +# error You do not have strncasecmp on your system. +#endif /* HAVE_STRNCASECMP */ + + +static const char* json_null_str = "null"; +static const char* json_true_str = "true"; +static const char* json_false_str = "false"; + +const char* json_tokener_errors[] = { + "success", + "continue", + "nesting to deep", + "unexpected end of data", + "unexpected character", + "null expected", + "boolean expected", + "number expected", + "array value separator ',' expected", + "quoted object property name expected", + "object property name separator ':' expected", + "object value separator ',' expected", + "invalid string sequence", + "expected comment", +}; + + +struct json_tokener* json_tokener_new() +{ + struct json_tokener *tok = calloc(1, sizeof(struct json_tokener)); + tok->pb = printbuf_new(); + json_tokener_reset(tok); + return tok; +} + +void json_tokener_free(struct json_tokener *tok) +{ + json_tokener_reset(tok); + if(tok) printbuf_free(tok->pb); + free(tok); +} + +static void json_tokener_reset_level(struct json_tokener *tok, int depth) +{ + tok->stack[depth].state = json_tokener_state_eatws; + tok->stack[depth].saved_state = json_tokener_state_start; + json_object_put(tok->stack[depth].current); + tok->stack[depth].current = NULL; + free(tok->stack[depth].obj_field_name); + tok->stack[depth].obj_field_name = NULL; +} + +void json_tokener_reset(struct json_tokener *tok) +{ + int i; + for(i = tok->depth; i >= 0; i--) + json_tokener_reset_level(tok, i); + tok->depth = 0; + tok->err = json_tokener_success; +} + +struct json_object* json_tokener_parse(char *str) +{ + struct json_tokener* tok; + struct json_object* obj; + + tok = json_tokener_new(); + obj = json_tokener_parse_ex(tok, str, -1); + if(tok->err != json_tokener_success) + obj = error_ptr(-tok->err); + json_tokener_free(tok); + return obj; +} + + +#if !HAVE_STRNDUP +/* CAW: compliant version of strndup() */ +char* strndup(const char* str, size_t n) +{ + if(str) { + size_t len = strlen(str); + size_t nn = min(len,n); + char* s = (char*)malloc(sizeof(char) * (nn + 1)); + + if(s) { + memcpy(s, str, nn); + s[nn] = '\0'; + } + + return s; + } + + return NULL; +} +#endif + + +#define state tok->stack[tok->depth].state +#define saved_state tok->stack[tok->depth].saved_state +#define current tok->stack[tok->depth].current +#define obj_field_name tok->stack[tok->depth].obj_field_name + +struct json_object* json_tokener_parse_ex(struct json_tokener *tok, + char *str, int len) +{ + struct json_object *obj = NULL; + char c; + + tok->char_offset = 0; + tok->err = json_tokener_success; + + do { + if(tok->char_offset == len) { + if(tok->depth == 0 && state == json_tokener_state_eatws && + saved_state == json_tokener_state_finish) + tok->err = json_tokener_success; + else + tok->err = json_tokener_continue; + goto out; + } + + c = *str; + redo_char: + switch(state) { + + case json_tokener_state_eatws: + if(isspace(c)) { + /* okay */ + } else if(c == '/') { + printbuf_reset(tok->pb); + printbuf_memappend(tok->pb, &c, 1); + state = json_tokener_state_comment_start; + } else { + state = saved_state; + goto redo_char; + } + break; + + case json_tokener_state_start: + switch(c) { + case '{': + state = json_tokener_state_eatws; + saved_state = json_tokener_state_object_field_start; + current = json_object_new_object(); + break; + case '[': + state = json_tokener_state_eatws; + saved_state = json_tokener_state_array; + current = json_object_new_array(); + break; + case 'N': + case 'n': + state = json_tokener_state_null; + printbuf_reset(tok->pb); + tok->st_pos = 0; + goto redo_char; + case '"': + case '\'': + state = json_tokener_state_string; + printbuf_reset(tok->pb); + tok->quote_char = c; + break; + case 'T': + case 't': + case 'F': + case 'f': + state = json_tokener_state_boolean; + printbuf_reset(tok->pb); + tok->st_pos = 0; + goto redo_char; +#if defined(__GNUC__) + case '0' ... '9': +#else + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': +#endif + case '-': + state = json_tokener_state_number; + printbuf_reset(tok->pb); + tok->is_double = 0; + goto redo_char; + default: + tok->err = json_tokener_error_parse_unexpected; + goto out; + } + break; + + case json_tokener_state_finish: + if(tok->depth == 0) goto out; + obj = json_object_get(current); + json_tokener_reset_level(tok, tok->depth); + tok->depth--; + goto redo_char; + + case json_tokener_state_null: + printbuf_memappend(tok->pb, &c, 1); + if(strncasecmp(json_null_str, tok->pb->buf, + min(tok->st_pos+1, strlen(json_null_str))) == 0) { + if(tok->st_pos == strlen(json_null_str)) { + current = NULL; + saved_state = json_tokener_state_finish; + state = json_tokener_state_eatws; + goto redo_char; + } + } else { + tok->err = json_tokener_error_parse_null; + goto out; + } + tok->st_pos++; + break; + + case json_tokener_state_comment_start: + if(c == '*') { + state = json_tokener_state_comment; + } else if(c == '/') { + state = json_tokener_state_comment_eol; + } else { + tok->err = json_tokener_error_parse_comment; + goto out; + } + printbuf_memappend(tok->pb, &c, 1); + break; + + case json_tokener_state_comment: + if(c == '*') state = json_tokener_state_comment_end; + printbuf_memappend(tok->pb, &c, 1); + break; + + case json_tokener_state_comment_eol: + if(c == '\n') { + MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf); + state = json_tokener_state_eatws; + } else { + printbuf_memappend(tok->pb, &c, 1); + } + break; + + case json_tokener_state_comment_end: + printbuf_memappend(tok->pb, &c, 1); + if(c == '/') { + MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf); + state = json_tokener_state_eatws; + } else { + state = json_tokener_state_comment; + } + break; + + case json_tokener_state_string: + if(c == tok->quote_char) { + current = json_object_new_string(tok->pb->buf); + saved_state = json_tokener_state_finish; + state = json_tokener_state_eatws; + } else if(c == '\\') { + saved_state = json_tokener_state_string; + state = json_tokener_state_string_escape; + } else { + printbuf_memappend(tok->pb, &c, 1); + } + break; + + case json_tokener_state_string_escape: + switch(c) { + case '"': + case '\\': + case '/': + printbuf_memappend(tok->pb, &c, 1); + state = saved_state; + break; + case 'b': + case 'n': + case 'r': + case 't': + if(c == 'b') printbuf_memappend(tok->pb, "\b", 1); + else if(c == 'n') printbuf_memappend(tok->pb, "\n", 1); + else if(c == 'r') printbuf_memappend(tok->pb, "\r", 1); + else if(c == 't') printbuf_memappend(tok->pb, "\t", 1); + state = saved_state; + break; + case 'u': + tok->ucs_char = 0; + tok->st_pos = 0; + state = json_tokener_state_escape_unicode; + break; + default: + tok->err = json_tokener_error_parse_string; + goto out; + } + break; + + case json_tokener_state_escape_unicode: + if(strchr(json_hex_chars, c)) { + tok->ucs_char += ((unsigned int)hexdigit(c) << ((3-tok->st_pos++)*4)); + if(tok->st_pos == 4) { + unsigned char utf_out[3]; + if (tok->ucs_char < 0x80) { + utf_out[0] = tok->ucs_char; + printbuf_memappend(tok->pb, (char*)utf_out, 1); + } else if (tok->ucs_char < 0x800) { + utf_out[0] = 0xc0 | (tok->ucs_char >> 6); + utf_out[1] = 0x80 | (tok->ucs_char & 0x3f); + printbuf_memappend(tok->pb, (char*)utf_out, 2); + } else { + utf_out[0] = 0xe0 | (tok->ucs_char >> 12); + utf_out[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f); + utf_out[2] = 0x80 | (tok->ucs_char & 0x3f); + printbuf_memappend(tok->pb, (char*)utf_out, 3); + } + state = saved_state; + } + } else { + tok->err = json_tokener_error_parse_string; + goto out; + } + break; + + case json_tokener_state_boolean: + printbuf_memappend(tok->pb, &c, 1); + if(strncasecmp(json_true_str, tok->pb->buf, + min(tok->st_pos+1, strlen(json_true_str))) == 0) { + if(tok->st_pos == strlen(json_true_str)) { + current = json_object_new_boolean(1); + saved_state = json_tokener_state_finish; + state = json_tokener_state_eatws; + goto redo_char; + } + } else if(strncasecmp(json_false_str, tok->pb->buf, + min(tok->st_pos+1, strlen(json_false_str))) == 0) { + if(tok->st_pos == strlen(json_false_str)) { + current = json_object_new_boolean(0); + saved_state = json_tokener_state_finish; + state = json_tokener_state_eatws; + goto redo_char; + } + } else { + tok->err = json_tokener_error_parse_boolean; + goto out; + } + tok->st_pos++; + break; + + case json_tokener_state_number: + if(c && strchr(json_number_chars, c)) { + printbuf_memappend(tok->pb, &c, 1); + if(c == '.' || c == 'e' || c == 'E') tok->is_double = 1; + } else { + int numi; + double numd; + if(!tok->is_double && sscanf(tok->pb->buf, "%d", &numi) == 1) { + current = json_object_new_int(numi); + } else if(tok->is_double && sscanf(tok->pb->buf, "%lf", &numd) == 1) { + current = json_object_new_double(numd); + } else { + tok->err = json_tokener_error_parse_number; + goto out; + } + saved_state = json_tokener_state_finish; + state = json_tokener_state_eatws; + goto redo_char; + } + break; + + case json_tokener_state_array: + if(c == ']') { + saved_state = json_tokener_state_finish; + state = json_tokener_state_eatws; + } else { + if(tok->depth >= JSON_TOKENER_MAX_DEPTH-1) { + tok->err = json_tokener_error_depth; + goto out; + } + state = json_tokener_state_array_add; + tok->depth++; + json_tokener_reset_level(tok, tok->depth); + goto redo_char; + } + break; + + case json_tokener_state_array_add: + json_object_array_add(current, obj); + saved_state = json_tokener_state_array_sep; + state = json_tokener_state_eatws; + goto redo_char; + + case json_tokener_state_array_sep: + if(c == ']') { + saved_state = json_tokener_state_finish; + state = json_tokener_state_eatws; + } else if(c == ',') { + saved_state = json_tokener_state_array; + state = json_tokener_state_eatws; + } else { + tok->err = json_tokener_error_parse_array; + goto out; + } + break; + + case json_tokener_state_object_field_start: + if(c == '}') { + saved_state = json_tokener_state_finish; + state = json_tokener_state_eatws; + } else if (c == '"' || c == '\'') { + tok->quote_char = c; + printbuf_reset(tok->pb); + state = json_tokener_state_object_field; + } else { + tok->err = json_tokener_error_parse_object_key_name; + goto out; + } + break; + + case json_tokener_state_object_field: + if(c == tok->quote_char) { + obj_field_name = strdup(tok->pb->buf); + saved_state = json_tokener_state_object_field_end; + state = json_tokener_state_eatws; + } else if(c == '\\') { + saved_state = json_tokener_state_object_field; + state = json_tokener_state_string_escape; + } else { + printbuf_memappend(tok->pb, &c, 1); + } + break; + + case json_tokener_state_object_field_end: + if(c == ':') { + saved_state = json_tokener_state_object_value; + state = json_tokener_state_eatws; + } else { + tok->err = json_tokener_error_parse_object_key_sep; + goto out; + } + break; + + case json_tokener_state_object_value: + if(tok->depth >= JSON_TOKENER_MAX_DEPTH-1) { + tok->err = json_tokener_error_depth; + goto out; + } + state = json_tokener_state_object_value_add; + tok->depth++; + json_tokener_reset_level(tok, tok->depth); + goto redo_char; + + case json_tokener_state_object_value_add: + json_object_object_add(current, obj_field_name, obj); + free(obj_field_name); + obj_field_name = NULL; + saved_state = json_tokener_state_object_sep; + state = json_tokener_state_eatws; + goto redo_char; + + case json_tokener_state_object_sep: + if(c == '}') { + saved_state = json_tokener_state_finish; + state = json_tokener_state_eatws; + } else if(c == ',') { + saved_state = json_tokener_state_object_field_start; + state = json_tokener_state_eatws; + } else { + tok->err = json_tokener_error_parse_object_value_sep; + goto out; + } + break; + + } + str++; + tok->char_offset++; + } while(c); + + if(state != json_tokener_state_finish && + saved_state != json_tokener_state_finish) + tok->err = json_tokener_error_parse_eof; + + out: + if(tok->err == json_tokener_success) return json_object_get(current); + MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n", + json_tokener_errors[tok->err], tok->char_offset); + return NULL; +} diff -NaurbB sdcc-src-3.1.0/src/json/json/json_tokener.h sdcc-src-3.1.0-pblaze/src/json/json/json_tokener.h --- sdcc-src-3.1.0/src/json/json/json_tokener.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/json/json_tokener.h 2011-02-07 20:04:46.000000000 +0100 @@ -0,0 +1,90 @@ +/* + * $Id: json_tokener.h,v 1.10 2006/07/25 03:24:50 mclark Exp $ + * + * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. + * Michael Clark <michael@metaparadigm.com> + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See COPYING for details. + * + */ + +#ifndef _json_tokener_h_ +#define _json_tokener_h_ + +#include <stddef.h> +#include "json_object.h" + +enum json_tokener_error { + json_tokener_success, + json_tokener_continue, + json_tokener_error_depth, + json_tokener_error_parse_eof, + json_tokener_error_parse_unexpected, + json_tokener_error_parse_null, + json_tokener_error_parse_boolean, + json_tokener_error_parse_number, + json_tokener_error_parse_array, + json_tokener_error_parse_object_key_name, + json_tokener_error_parse_object_key_sep, + json_tokener_error_parse_object_value_sep, + json_tokener_error_parse_string, + json_tokener_error_parse_comment +}; + +enum json_tokener_state { + json_tokener_state_eatws, + json_tokener_state_start, + json_tokener_state_finish, + json_tokener_state_null, + json_tokener_state_comment_start, + json_tokener_state_comment, + json_tokener_state_comment_eol, + json_tokener_state_comment_end, + json_tokener_state_string, + json_tokener_state_string_escape, + json_tokener_state_escape_unicode, + json_tokener_state_boolean, + json_tokener_state_number, + json_tokener_state_array, + json_tokener_state_array_add, + json_tokener_state_array_sep, + json_tokener_state_object_field_start, + json_tokener_state_object_field, + json_tokener_state_object_field_end, + json_tokener_state_object_value, + json_tokener_state_object_value_add, + json_tokener_state_object_sep +}; + +struct json_tokener_srec +{ + enum json_tokener_state state, saved_state; + struct json_object *obj; + struct json_object *current; + char *obj_field_name; +}; + +#define JSON_TOKENER_MAX_DEPTH 32 + +struct json_tokener +{ + char *str; + struct printbuf *pb; + int depth, is_double, st_pos, char_offset; + ptrdiff_t err; + unsigned int ucs_char; + char quote_char; + struct json_tokener_srec stack[JSON_TOKENER_MAX_DEPTH]; +}; + +extern const char* json_tokener_errors[]; + +extern struct json_tokener* json_tokener_new(void); +extern void json_tokener_free(struct json_tokener *tok); +extern void json_tokener_reset(struct json_tokener *tok); +extern struct json_object* json_tokener_parse(char *str); +extern struct json_object* json_tokener_parse_ex(struct json_tokener *tok, + char *str, int len); + +#endif diff -NaurbB sdcc-src-3.1.0/src/json/json/json_util.c sdcc-src-3.1.0-pblaze/src/json/json/json_util.c --- sdcc-src-3.1.0/src/json/json/json_util.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/json/json_util.c 2011-02-07 20:04:46.000000000 +0100 @@ -0,0 +1,122 @@ +/* + * $Id: json_util.c,v 1.4 2006/01/30 23:07:57 mclark Exp $ + * + * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. + * Michael Clark <michael@metaparadigm.com> + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See COPYING for details. + * + */ + +#include "config.h" + +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <limits.h> +#include <string.h> +#include <errno.h> + +#if HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif /* HAVE_SYS_TYPES_H */ + +#if HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif /* HAVE_SYS_STAT_H */ + +#if HAVE_FCNTL_H +#include <fcntl.h> +#endif /* HAVE_FCNTL_H */ + +#if HAVE_UNISTD_H +# include <unistd.h> +#endif /* HAVE_UNISTD_H */ + +#ifdef WIN32 +# define WIN32_LEAN_AND_MEAN +# include <windows.h> +# include <io.h> +#endif /* defined(WIN32) */ + +#if !HAVE_OPEN && defined(WIN32) +# define open _open +#endif + + +#include "bits.h" +#include "debug.h" +#include "printbuf.h" +#include "json_object.h" +#include "json_tokener.h" +#include "json_util.h" + +struct json_object* json_object_from_file(char *filename) +{ + struct printbuf *pb; + struct json_object *obj; + char buf[JSON_FILE_BUF_SIZE]; + int fd, ret; + + if((fd = open(filename, O_RDONLY)) < 0) { + MC_ERROR("json_object_from_file: error reading file %s: %s\n", + filename, strerror(errno)); + return error_ptr(-1); + } + if(!(pb = printbuf_new())) { + MC_ERROR("json_object_from_file: printbuf_new failed\n"); + return error_ptr(-1); + } + while((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0) { + printbuf_memappend(pb, buf, ret); + } + close(fd); + if(ret < 0) { + MC_ABORT("json_object_from_file: error reading file %s: %s\n", + filename, strerror(errno)); + printbuf_free(pb); + return error_ptr(-1); + } + obj = json_tokener_parse(pb->buf); + printbuf_free(pb); + return obj; +} + +int json_object_to_file(char *filename, struct json_object *obj) +{ + const char *json_str; + int fd, ret; + unsigned int wpos, wsize; + + if(!obj) { + MC_ERROR("json_object_to_file: object is null\n"); + return -1; + } + + if((fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0) { + MC_ERROR("json_object_to_file: error opening file %s: %s\n", + filename, strerror(errno)); + return -1; + } + + if(!(json_str = json_object_to_json_string(obj))) { return -1; } + + + wsize = (unsigned int)(strlen(json_str) & UINT_MAX); /* CAW: probably unnecessary, but the most 64bit safe */ + wpos = 0; + while(wpos < wsize) { + if((ret = write(fd, json_str + wpos, wsize-wpos)) < 0) { + close(fd); + MC_ERROR("json_object_to_file: error writing file %s: %s\n", + filename, strerror(errno)); + return -1; + } + + /* because of the above check for ret < 0, we can safely cast and add */ + wpos += (unsigned int)ret; + } + + close(fd); + return 0; +} diff -NaurbB sdcc-src-3.1.0/src/json/json/json_util.h sdcc-src-3.1.0-pblaze/src/json/json/json_util.h --- sdcc-src-3.1.0/src/json/json/json_util.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/json/json_util.h 2011-02-07 20:04:46.000000000 +0100 @@ -0,0 +1,23 @@ +/* + * $Id: json_util.h,v 1.4 2006/01/30 23:07:57 mclark Exp $ + * + * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. + * Michael Clark <michael@metaparadigm.com> + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See COPYING for details. + * + */ + +#ifndef _json_util_h_ +#define _json_util_h_ + +#include "json_object.h" + +#define JSON_FILE_BUF_SIZE 4096 + +/* utlitiy functions */ +extern struct json_object* json_object_from_file(char *filename); +extern int json_object_to_file(char *filename, struct json_object *obj); + +#endif diff -NaurbB sdcc-src-3.1.0/src/json/json/linkhash.c sdcc-src-3.1.0-pblaze/src/json/json/linkhash.c --- sdcc-src-3.1.0/src/json/json/linkhash.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/json/linkhash.c 2011-02-07 20:04:46.000000000 +0100 @@ -0,0 +1,218 @@ +/* + * $Id: linkhash.c,v 1.4 2006/01/26 02:16:28 mclark Exp $ + * + * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. + * Michael Clark <michael@metaparadigm.com> + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See COPYING for details. + * + */ + +#include "config.h" + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <stdarg.h> +#include <stddef.h> +#include <limits.h> + +#include "linkhash.h" + +void lh_abort(const char *msg, ...) +{ + va_list ap; + va_start(ap, msg); + vprintf(msg, ap); + va_end(ap); + exit(1); +} + +unsigned long lh_ptr_hash(const void *k) +{ + /* CAW: refactored to be 64bit nice */ + return (unsigned long)((((ptrdiff_t)k * LH_PRIME) >> 4) & ULONG_MAX); +} + +int lh_ptr_equal(const void *k1, const void *k2) +{ + return (k1 == k2); +} + +unsigned long lh_char_hash(const void *k) +{ + unsigned int h = 0; + const char* data = k; + + while( *data!=0 ) h = h*129 + (unsigned int)(*data++) + LH_PRIME; + + return h; +} + +int lh_char_equal(const void *k1, const void *k2) +{ + return (strcmp((const char*)k1, (const char*)k2) == 0); +} + +struct lh_table* lh_table_new(int size, const char *name, + lh_entry_free_fn *free_fn, + lh_hash_fn *hash_fn, + lh_equal_fn *equal_fn) +{ + int i; + struct lh_table *t; + + t = calloc(1, sizeof(struct lh_table)); + if(!t) lh_abort("lh_table_new: calloc failed\n"); + t->count = 0; + t->size = size; + t->name = name; + t->table = calloc(size, sizeof(struct lh_entry)); + if(!t->table) lh_abort("lh_table_new: calloc failed\n"); + t->free_fn = free_fn; + t->hash_fn = hash_fn; + t->equal_fn = equal_fn; + for(i = 0; i < size; i++) t->table[i].k = LH_EMPTY; + return t; +} + +struct lh_table* lh_kchar_table_new(int size, const char *name, + lh_entry_free_fn *free_fn) +{ + return lh_table_new(size, name, free_fn, lh_char_hash, lh_char_equal); +} + +struct lh_table* lh_kptr_table_new(int size, const char *name, + lh_entry_free_fn *free_fn) +{ + return lh_table_new(size, name, free_fn, lh_ptr_hash, lh_ptr_equal); +} + +void lh_table_resize(struct lh_table *t, int new_size) +{ + struct lh_table *new_t; + struct lh_entry *ent; + + new_t = lh_table_new(new_size, t->name, NULL, t->hash_fn, t->equal_fn); + ent = t->head; + while(ent) { + lh_table_insert(new_t, ent->k, ent->v); + ent = ent->next; + } + free(t->table); + t->table = new_t->table; + t->size = new_size; + t->head = new_t->head; + t->tail = new_t->tail; + t->resizes++; + free(new_t); +} + +void lh_table_free(struct lh_table *t) +{ + struct lh_entry *c; + for(c = t->head; c != NULL; c = c->next) { + if(t->free_fn) { + t->free_fn(c); + } + } + free(t->table); + free(t); +} + + +int lh_table_insert(struct lh_table *t, void *k, const void *v) +{ + unsigned long h, n; + + t->inserts++; + if(t->count > t->size * 0.66) lh_table_resize(t, t->size * 2); + + h = t->hash_fn(k); + n = h % t->size; + + while( 1 ) { + if(t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED) break; + t->collisions++; + if(++n == t->size) n = 0; + } + + t->table[n].k = k; + t->table[n].v = v; + t->count++; + + if(t->head == NULL) { + t->head = t->tail = &t->table[n]; + t->table[n].next = t->table[n].prev = NULL; + } else { + t->tail->next = &t->table[n]; + t->table[n].prev = t->tail; + t->table[n].next = NULL; + t->tail = &t->table[n]; + } + + return 0; +} + + +struct lh_entry* lh_table_lookup_entry(struct lh_table *t, const void *k) +{ + unsigned long h = t->hash_fn(k); + unsigned long n = h % t->size; + + t->lookups++; + while( 1 ) { + if(t->table[n].k == LH_EMPTY) return NULL; + if(t->table[n].k != LH_FREED && + t->equal_fn(t->table[n].k, k)) return &t->table[n]; + if(++n == t->size) n = 0; + } + return NULL; +} + + +const void* lh_table_lookup(struct lh_table *t, const void *k) +{ + struct lh_entry *e = lh_table_lookup_entry(t, k); + if(e) return e->v; + return NULL; +} + + +int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e) +{ + ptrdiff_t n = (ptrdiff_t)(e - t->table); /* CAW: fixed to be 64bit nice, still need the crazy negative case... */ + + /* CAW: this is bad, really bad, maybe stack goes other direction on this machine... */ + if(n < 0) { return -2; } + + if(t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED) return -1; + t->count--; + if(t->free_fn) t->free_fn(e); + t->table[n].v = NULL; + t->table[n].k = LH_FREED; + if(t->tail == &t->table[n] && t->head == &t->table[n]) { + t->head = t->tail = NULL; + } else if (t->head == &t->table[n]) { + t->head->next->prev = NULL; + t->head = t->head->next; + } else if (t->tail == &t->table[n]) { + t->tail->prev->next = NULL; + t->tail = t->tail->prev; + } else { + t->table[n].prev->next = t->table[n].next; + t->table[n].next->prev = t->table[n].prev; + } + t->table[n].next = t->table[n].prev = NULL; + return 0; +} + + +int lh_table_delete(struct lh_table *t, const void *k) +{ + struct lh_entry *e = lh_table_lookup_entry(t, k); + if(!e) return -1; + return lh_table_delete_entry(t, e); +} + diff -NaurbB sdcc-src-3.1.0/src/json/json/linkhash.h sdcc-src-3.1.0-pblaze/src/json/json/linkhash.h --- sdcc-src-3.1.0/src/json/json/linkhash.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/json/linkhash.h 2011-02-07 20:04:46.000000000 +0100 @@ -0,0 +1,264 @@ +/* + * $Id: linkhash.h,v 1.6 2006/01/30 23:07:57 mclark Exp $ + * + * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. + * Michael Clark <michael@metaparadigm.com> + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See COPYING for details. + * + */ + +#ifndef _linkhash_h_ +#define _linkhash_h_ + +/** + * golden prime used in hash functions + */ +#define LH_PRIME 0x9e370001UL + +/** + * sentinel pointer value for empty slots + */ +#define LH_EMPTY (void*)-1 + +/** + * sentinel pointer value for freed slots + */ +#define LH_FREED (void*)-2 + +struct lh_entry; + +/** + * callback function prototypes + */ +typedef void (lh_entry_free_fn) (struct lh_entry *e); +/** + * callback function prototypes + */ +typedef unsigned long (lh_hash_fn) (const void *k); +/** + * callback function prototypes + */ +typedef int (lh_equal_fn) (const void *k1, const void *k2); + +/** + * An entry in the hash table + */ +struct lh_entry { + /** + * The key. + */ + void *k; + /** + * The value. + */ + const void *v; + /** + * The next entry + */ + struct lh_entry *next; + /** + * The previous entry. + */ + struct lh_entry *prev; +}; + + +/** + * The hash table structure. + */ +struct lh_table { + /** + * Size of our hash. + */ + int size; + /** + * Numbers of entries. + */ + int count; + + /** + * Number of collisions. + */ + int collisions; + + /** + * Number of resizes. + */ + int resizes; + + /** + * Number of lookups. + */ + int lookups; + + /** + * Number of inserts. + */ + int inserts; + + /** + * Number of deletes. + */ + int deletes; + + /** + * Name of the hash table. + */ + const char *name; + + /** + * The first entry. + */ + struct lh_entry *head; + + /** + * The last entry. + */ + struct lh_entry *tail; + + struct lh_entry *table; + + /** + * A pointer onto the function responsible for freeing an entry. + */ + lh_entry_free_fn *free_fn; + lh_hash_fn *hash_fn; + lh_equal_fn *equal_fn; +}; + + +/** + * Pre-defined hash and equality functions + */ +extern unsigned long lh_ptr_hash(const void *k); +extern int lh_ptr_equal(const void *k1, const void *k2); + +extern unsigned long lh_char_hash(const void *k); +extern int lh_char_equal(const void *k1, const void *k2); + + +/** + * Convenience list iterator. + */ +#define lh_foreach(table, entry) \ +for(entry = table->head; entry; entry = entry->next) + +/** + * lh_foreach_safe allows calling of deletion routine while iterating. + */ +#define lh_foreach_safe(table, entry, tmp) \ +for(entry = table->head; entry && ((tmp = entry->next) || 1); entry = tmp) + + + +/** + * Create a new linkhash table. + * @param size initial table size. The table is automatically resized + * although this incurs a performance penalty. + * @param name the table name. + * @param free_fn callback function used to free memory for entries + * when lh_table_free or lh_table_delete is called. + * If NULL is provided, then memory for keys and values + * must be freed by the caller. + * @param hash_fn function used to hash keys. 2 standard ones are defined: + * lh_ptr_hash and lh_char_hash for hashing pointer values + * and C strings respectively. + * @param equal_fn comparison function to compare keys. 2 standard ones defined: + * lh_ptr_hash and lh_char_hash for comparing pointer values + * and C strings respectively. + * @return a pointer onto the linkhash table. + */ +extern struct lh_table* lh_table_new(int size, const char *name, + lh_entry_free_fn *free_fn, + lh_hash_fn *hash_fn, + lh_equal_fn *equal_fn); + +/** + * Convenience function to create a new linkhash + * table with char keys. + * @param size initial table size. + * @param name table name. + * @param free_fn callback function used to free memory for entries. + * @return a pointer onto the linkhash table. + */ +extern struct lh_table* lh_kchar_table_new(int size, const char *name, + lh_entry_free_fn *free_fn); + + +/** + * Convenience function to create a new linkhash + * table with ptr keys. + * @param size initial table size. + * @param name table name. + * @param free_fn callback function used to free memory for entries. + * @return a pointer onto the linkhash table. + */ +extern struct lh_table* lh_kptr_table_new(int size, const char *name, + lh_entry_free_fn *free_fn); + + +/** + * Free a linkhash table. + * If a callback free function is provided then it is called for all + * entries in the table. + * @param t table to free. + */ +extern void lh_table_free(struct lh_table *t); + + +/** + * Insert a record into the table. + * @param t the table to insert into. + * @param k a pointer to the key to insert. + * @param v a pointer to the value to insert. + */ +extern int lh_table_insert(struct lh_table *t, void *k, const void *v); + + +/** + * Lookup a record into the table. + * @param t the table to lookup + * @param k a pointer to the key to lookup + * @return a pointer to the record structure of the value or NULL if it does not exist. + */ +extern struct lh_entry* lh_table_lookup_entry(struct lh_table *t, const void *k); + +/** + * Lookup a record into the table + * @param t the table to lookup + * @param k a pointer to the key to lookup + * @return a pointer to the found value or NULL if it does not exist. + */ +extern const void* lh_table_lookup(struct lh_table *t, const void *k); + + +/** + * Delete a record from the table. + * If a callback free function is provided then it is called for the + * for the item being deleted. + * @param t the table to delete from. + * @param e a pointer to the entry to delete. + * @return 0 if the item was deleted. + * @return -1 if it was not found. + */ +extern int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e); + + +/** + * Delete a record from the table. + * If a callback free function is provided then it is called for the + * for the item being deleted. + * @param t the table to delete from. + * @param k a pointer to the key to delete. + * @return 0 if the item was deleted. + * @return -1 if it was not found. + */ +extern int lh_table_delete(struct lh_table *t, const void *k); + + +void lh_abort(const char *msg, ...); +void lh_table_resize(struct lh_table *t, int new_size); + +#endif diff -NaurbB sdcc-src-3.1.0/src/json/json/printbuf.c sdcc-src-3.1.0-pblaze/src/json/json/printbuf.c --- sdcc-src-3.1.0/src/json/json/printbuf.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/json/printbuf.c 2011-02-07 20:04:46.000000000 +0100 @@ -0,0 +1,145 @@ +/* + * $Id: printbuf.c,v 1.5 2006/01/26 02:16:28 mclark Exp $ + * + * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. + * Michael Clark <michael@metaparadigm.com> + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See COPYING for details. + * + */ + +#include "config.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#if HAVE_STDARG_H +# include <stdarg.h> +#else /* !HAVE_STDARG_H */ +# error Not enough var arg support! +#endif /* HAVE_STDARG_H */ + +#include "bits.h" +#include "debug.h" +#include "printbuf.h" + +struct printbuf* printbuf_new() +{ + struct printbuf *p; + + if(!(p = calloc(1, sizeof(struct printbuf)))) return NULL; + p->size = 32; + p->bpos = 0; + if(!(p->buf = malloc(p->size))) { + free(p); + return NULL; + } + return p; +} + + +int printbuf_memappend(struct printbuf *p, const char *buf, int size) +{ + char *t; + if(p->size - p->bpos <= size) { + int new_size = max(p->size * 2, p->bpos + size + 8); +#ifdef PRINTBUF_DEBUG + MC_DEBUG("printbuf_memappend: realloc " + "bpos=%d wrsize=%d old_size=%d new_size=%d\n", + p->bpos, size, p->size, new_size); +#endif /* PRINTBUF_DEBUG */ + if(!(t = realloc(p->buf, new_size))) return -1; + p->size = new_size; + p->buf = t; + } + memcpy(p->buf + p->bpos, buf, size); + p->bpos += size; + p->buf[p->bpos]= '\0'; + return size; +} + +#if !HAVE_VSNPRINTF && defined(WIN32) +# define vsnprintf _vsnprintf +#elif !HAVE_VSNPRINTF /* !HAVE_VSNPRINTF */ +# error Need vsnprintf! +#endif /* !HAVE_VSNPRINTF && defined(WIN32) */ + +#if !HAVE_VASPRINTF +/* CAW: compliant version of vasprintf */ +static int vasprintf(char **buf, const char *fmt, va_list ap) +{ +#ifndef WIN32 + static char _T_emptybuffer = '\0'; +#endif /* !defined(WIN32) */ + int chars; + char *b; + + if(!buf) { return -1; } + +#ifdef WIN32 + chars = _vscprintf(fmt, ap)+1; +#else /* !defined(WIN32) */ + /* CAW: RAWR! We have to hope to god here that vsnprintf doesn't overwrite + our buffer like on some 64bit sun systems.... but hey, its time to move on */ + chars = vsnprintf(&_T_emptybuffer, 0, fmt, ap)+1; + if(chars < 0) { chars *= -1; } /* CAW: old glibc versions have this problem */ +#endif /* defined(WIN32) */ + + b = (char*)malloc(sizeof(char)*chars); + if(!b) { return -1; } + + if((chars = vsprintf(b, fmt, ap)) < 0) + { + free(b); + } else { + *buf = b; + } + + return chars; +} +#endif /* !HAVE_VASPRINTF */ + +int sprintbuf(struct printbuf *p, const char *msg, ...) +{ + va_list ap; + char *t; + int size; + char buf[128]; + + /* user stack buffer first */ + va_start(ap, msg); + size = vsnprintf(buf, 128, msg, ap); + va_end(ap); + /* if string is greater than stack buffer, then use dynamic string + with vasprintf. Note: some implementation of vsnprintf return -1 + if output is truncated whereas some return the number of bytes that + would have been writen - this code handles both cases. */ + if(size == -1 || size > 127) { + int ret; + va_start(ap, msg); + size = vasprintf(&t, msg, ap); + va_end(ap); + if(size == -1) return -1; + ret = printbuf_memappend(p, t, size); + free(t); + return ret; + } else { + return printbuf_memappend(p, buf, size); + } +} + +void printbuf_reset(struct printbuf *p) +{ + p->buf[0] = '\0'; + p->bpos = 0; +} + +void printbuf_free(struct printbuf *p) +{ + if(p) { + free(p->buf); + free(p); + } +} diff -NaurbB sdcc-src-3.1.0/src/json/json/printbuf.h sdcc-src-3.1.0-pblaze/src/json/json/printbuf.h --- sdcc-src-3.1.0/src/json/json/printbuf.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/json/printbuf.h 2011-02-07 20:04:44.000000000 +0100 @@ -0,0 +1,38 @@ +/* + * $Id: printbuf.h,v 1.4 2006/01/26 02:16:28 mclark Exp $ + * + * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. + * Michael Clark <michael@metaparadigm.com> + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See COPYING for details. + * + */ + +#ifndef _printbuf_h_ +#define _printbuf_h_ + +#undef PRINTBUF_DEBUG + +struct printbuf { + char *buf; + int bpos; + int size; +}; + +extern struct printbuf* +printbuf_new(void); + +extern int +printbuf_memappend(struct printbuf *p, const char *buf, int size); + +extern int +sprintbuf(struct printbuf *p, const char *msg, ...); + +extern void +printbuf_reset(struct printbuf *p); + +extern void +printbuf_free(struct printbuf *p); + +#endif diff -NaurbB sdcc-src-3.1.0/src/json/main.c sdcc-src-3.1.0-pblaze/src/json/main.c --- sdcc-src-3.1.0/src/json/main.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/main.c 2011-02-07 20:04:44.000000000 +0100 @@ -0,0 +1,380 @@ +/** @file main.c + json specific general functions. + + Note that mlh prepended _json_ on the static functions. Makes + it easier to set a breakpoint using the debugger. +*/ +#include "common.h" +#include "main.h" +#include "ralloc.h" +#include "gen.h" +#include "device.h" + +static char _defaultRules[] = { +#include "peeph.rul" +}; + +/* list of key words used by msc51 */ +static char *_json_keywords[] = { + "at", + "code", + "critical", + "eeprom", + "interrupt", + "sfr", + "xdata", + "_code", + "_eeprom", + "_generic", + "_xdata", + "sram", + "_sram", + "flash", + "_flash", + NULL +}; + +static int regParmFlg = 0; /* determine if we can register a parameter */ +json_options_t json_options; + +static void +_json_init (void) +{ + asm_addTree (&asm_asxxxx_mapping); +} + +static void +_json_reset_regparm (void) +{ + regParmFlg = 0; +} + + +void _json_genInitStartup (FILE * of) +{ + +} + + +static int +_json_regparm (sym_link * l, bool reentrant) +{ + /* the first eight bytes will be passed in + registers r16-r23. but we won't split variables + i.e. if not enough registers left to hold + the parameter then the whole parameter along + with rest of the parameters go onto the stack */ + if (regParmFlg < 8) { + int size; + if ((size = getSize (l)) > (8 - regParmFlg)) { + /* all remaining go on stack */ + regParmFlg = 8; + return 0; + } + regParmFlg += size; + return 1; + } + + return 0; +} + +void json_assignRegisters (ebbIndex *); + +#define GEN_JSON "--json" +#define GEN_JSONFILE "--json-file=" +#define ISOPT(str) !strncmp(argv[ *i ], str, strlen(str) ) + + + +// TODO +OPTION json_optionsTable[]= { + /* json debugging options */ /* code generation options */ + { 0, GEN_JSON, &json_options.json_flag, "dump iCodes in JSON format"}, + { 0, GEN_JSONFILE, &json_options.json_dumpfile, "JSON output filename"}, + { 0, NULL, NULL, NULL} +}; + +static bool +_json_parseOptions (int *pargc, char **argv, int *i) +{ + /* TODO: allow port-specific command line options to specify + * segment names here. + */ + int j=0; + //char *stkmodel; + + /* check for arguments that have associated an integer variable */ + while(json_optionsTable[j].pparameter) { + if(ISOPT( json_optionsTable[j].longOpt )) { + (*(int *)json_optionsTable[j].pparameter)++; + return TRUE; + } + j++; + } +/* + if(ISOPT(STACK_MODEL)) { + stkmodel = getStringArg(STACK_MODEL, argv, i, *pargc); + if(!STRCASECMP(stkmodel, "small"))picoBlaze_options.stack_model = 0; + else if(!STRCASECMP(stkmodel, "large"))picoBlaze_options.stack_model = 1; + else { + fprintf(stderr, "Unknown stack model: %s", stkmodel); + exit(EXIT_FAILURE); + } + return TRUE; + } + + if(ISOPT(IVT_LOC)) { + picoBlaze_options.ivt_loc = getIntArg(IVT_LOC, argv, i, *pargc); + fprintf(stderr, "%s:%d setting interrupt vector addresses 0x%x\n", __FILE__, __LINE__, picoBlaze_options.ivt_loc); + return TRUE; + } + + if(ISOPT(USE_CRT)) { + picoBlaze_options.no_crt = 0; + picoBlaze_options.crt_name = Safe_strdup( getStringArg(USE_CRT, argv, i, *pargc) ); + + return TRUE; + } + + if (ISOPT(NO_OPTIMIZE_GOTO)) { + picoBlaze_options.opt_flags |= OF_NO_OPTIMIZE_GOTO; + return TRUE; + } + + if(ISOPT(OPTIMIZE_CMP)) { + picoBlaze_options.opt_flags |= OF_OPTIMIZE_CMP; + return TRUE; + } + + if (ISOPT(OPTIMIZE_DF)) { + picoBlaze_options.opt_flags |= OF_OPTIMIZE_DF; + return TRUE; + } +*/ + + if (ISOPT(GEN_JSON)) { + json_options.json_flag = TRUE; + if (ISOPT(GEN_JSONFILE)) { // inside block because JSON and JSON-FILE have common starting substring checked in arguments + json_options.json_dumpfile = Safe_strdup( getStringArg(GEN_JSONFILE, argv, i, *pargc) ); + } + return TRUE; + } + + return FALSE; +} + +static void +_json_finaliseOptions (void) +{ + port->mem.default_local_map = port->mem.default_globl_map = xdata; + /* change stack to be in far space */ + /* internal stack segment ; + SFRSPACE - NO + FAR-SPACE - YES + PAGED - NO + DIRECT-ACCESS - NO + BIT-ACCESS - NO + CODE-ACESS - NO + DEBUG-NAME - 'B' + POINTER-TYPE - FPOINTER + */ + istack = + allocMap (0, 1, 0, 0, 0, 0, options.stack_loc, ISTACK_NAME, + 'B', FPOINTER); + + /* also change xdata to be direct space since we can use lds/sts */ + xdata->direct = 1; + +} + +static void +_json_setDefaultOptions (void) +{ + options.stackAuto = 1; + json_options.json_flag = 0; + json_options.json_dumpfile = "iCodeDumpFile.txt"; +} + +static const char * +_json_getRegName (struct regs *reg) +{ + if (reg) + return reg->name; + return "err"; +} + +static void +_json_genAssemblerPreamble (FILE * of) +{ + +} + +/* Generate interrupt vector table. */ +static int +_json_genIVT (struct dbuf_s * oBuf, symbol ** interrupts, int maxInterrupts) +{ + return TRUE; +} + +/* Indicate which extended bit operations this port supports */ +static bool +hasExtBitOp (int op, int size) +{ + if (op == RRC + || op == RLC + || op == GETHBIT + ) + return TRUE; + else + return FALSE; +} + +/* Indicate the expense of an access to an output storage class */ +static int +oclsExpense (struct memmap *oclass) +{ + if (IN_FARSPACE(oclass)) + return 1; + + return 0; +} + +/** $1 is always the basename. + $2 is always the output file. + $3 varies + $l is the list of extra options that should be there somewhere... + MUST be terminated with a NULL. +*/ +static const char *_linkCmd[] = { + //"linkjson", "", "\"$1\"", NULL + NULL +}; + +/* $3 is replaced by assembler.debug_opts resp. port->assembler.plain_opts */ +static const char *_asmCmd[] = { + //"asjson", "$l" , "$3", "\"$1.s\"", NULL + NULL +}; + +/* Globals */ +PORT json_port = { + TARGET_ID_JSON, + "json", + "Json iCodes", /* Target name */ + NULL, /* processor */ + { + glue, + TRUE, /* Emit glue around main */ + MODEL_LARGE | MODEL_SMALL, + MODEL_SMALL, + NULL, /* model == target */ + }, + { + _asmCmd, + NULL, + "-plosgff", /* Options with debug */ + "-plosgff", /* Options without debug */ + 0, + ".s", + NULL, /* no do_assemble */ + }, + { + NULL, + NULL, + NULL, + ".rel", + 1}, + { + _defaultRules}, + { + /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */ + 1, 2, 2, 4, 1, 2, 2, 1, 4, 4}, + + /* tags for generic pointers */ + { 0x00, 0x40, 0x60, 0x80 }, /* far, near, xstack, code */ + + { + "XSEG", + "STACK", + "CSEG", + "DSEG", + "ISEG", + NULL, //PSEG + "XSEG", + "BSEG", + "RSEG", + "GSINIT", + "OSEG", + "GSFINAL", + "HOME", + NULL, // initialized xdata + NULL, // a code copy of xiseg + "CONST (CODE)", // const_name - const data (code or not) + "CABS (ABS,CODE)", // cabs_name - const absolute data (code or not) + "XABS (ABS,XDATA)", // xabs_name - absolute xdata/pdata + "IABS (ABS,DATA)", // iabs_name - absolute idata/data + NULL, + NULL, + 0, + }, + { NULL, NULL }, + { + -1, 1, 4, 1, 1, 0}, + /* pblaze hasn't any mul */ + { + 1, -1 + }, + { + json_emitDebuggerSymbol + }, + { + 32, /* maxCount */ + 2, /* sizeofElement */ + /* The rest of these costs are bogus. They approximate */ + /* the behavior of src/SDCCicode.c 1.207 and earlier. */ + {2,2,2}, /* sizeofMatchJump[] */ + {0,0,0}, /* sizeofRangeCompare[] */ + 0, /* sizeofSubtract */ + 2, /* sizeofDispatch */ + }, + "_", + _json_init, + _json_parseOptions, + json_optionsTable, + NULL, + _json_finaliseOptions, + _json_setDefaultOptions, + json_assignRegisters, + _json_getRegName, + _json_keywords, + _json_genAssemblerPreamble, + NULL, /* no genAssemblerEnd */ + _json_genIVT, + NULL, // _json_genXINIT + _json_genInitStartup, /* genInitStartup */ + _json_reset_regparm, + _json_regparm, + NULL, + NULL, + NULL, + hasExtBitOp, /* hasExtBitOp */ + oclsExpense, /* oclsExpense */ + FALSE, + TRUE, /* little endian */ + 0, /* leave lt */ + 1, /* transform gt ==> not le */ + 0, /* leave le */ + 0, /* leave ge */ + 0, /* leave != */ + 0, /* leave == */ + FALSE, /* No array initializer support. */ + 0, /* no CSE cost estimation yet */ + NULL, /* no builtin functions */ + GPOINTER, /* treat unqualified pointers as "generic" pointers */ + 1, /* reset labelKey to 1 */ + 1, /* globals & local static allowed */ + PORT_MAGIC +}; + + + diff -NaurbB sdcc-src-3.1.0/src/json/main.h sdcc-src-3.1.0-pblaze/src/json/main.h --- sdcc-src-3.1.0/src/json/main.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/main.h 2011-02-07 20:04:48.000000000 +0100 @@ -0,0 +1,8 @@ +#ifndef MAIN_INCLUDE +#define MAIN_INCLUDE + +bool x_parseOptions (char **argv, int *pargc); +void x_setDefaultOptions (void); +void x_finaliseOptions (void); + +#endif diff -NaurbB sdcc-src-3.1.0/src/json/peeph.rul sdcc-src-3.1.0-pblaze/src/json/peeph.rul --- sdcc-src-3.1.0/src/json/peeph.rul 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/peeph.rul 2011-02-07 20:04:44.000000000 +0100 @@ -0,0 +1,1676 @@ +/* Generated file, DO NOT Edit! */ +/* To Make changes to rules edit */ +/* <port>/peeph.def instead. */ +"\n" +"\n" +"replace restart {\n" +" xch a,%1\n" +" xch a,%1\n" +"} by {\n" +" ; Peephole 2.a removed redundant xch xch\n" +"}\n" +"\n" +"replace restart {\n" +" mov %1,#0x00\n" +" mov a,#0x00\n" +"} by {\n" +" ; Peephole 3.a changed mov to clr\n" +" clr a\n" +" mov %1,a\n" +"}\n" +"\n" +"replace restart {\n" +" mov %1,#0x00\n" +" clr a\n" +"} by {\n" +" ; Peephole 3.b changed mov to clr\n" +" clr a\n" +" mov %1,a\n" +"}\n" +"\n" +"replace restart {\n" +" mov %1,#0x00\n" +" mov %2,#0x00\n" +" mov a,%3\n" +"} by {\n" +" ; Peephole 3.c changed mov to clr\n" +" clr a\n" +" mov %1,a\n" +" mov %2,a\n" +" mov a,%3\n" +"}\n" +"\n" +"\n" +"\n" +"replace {\n" +" mov %1,a\n" +" mov dptr,#%2\n" +" mov a,%1\n" +" movx @dptr,a\n" +"} by {\n" +" ; Peephole 100 removed redundant mov\n" +" mov %1,a\n" +" mov dptr,#%2\n" +" movx @dptr,a\n" +"}\n" +"\n" +"replace {\n" +" mov a,acc\n" +"} by {\n" +" ; Peephole 100.a removed redundant mov\n" +"}\n" +"\n" +"replace {\n" +" mov a,%1\n" +" movx @dptr,a\n" +" inc dptr\n" +" mov a,%1\n" +" movx @dptr,a\n" +"} by {\n" +" ; Peephole 101 removed redundant mov\n" +" mov a,%1\n" +" movx @dptr,a\n" +" inc dptr\n" +" movx @dptr,a\n" +"}\n" +"\n" +"replace {\n" +" mov %1,%2\n" +" ljmp %3\n" +"%4:\n" +" mov %1,%5\n" +"%3:\n" +" mov dpl,%1\n" +"%7:\n" +" mov sp,bp\n" +" pop bp\n" +"} by {\n" +" ; Peephole 102 removed redundant mov\n" +" mov dpl,%2\n" +" ljmp %3\n" +"%4:\n" +" mov dpl,%5\n" +"%3:\n" +"%7:\n" +" mov sp,bp\n" +" pop bp\n" +"}\n" +"\n" +"replace {\n" +" mov %1,%2\n" +" ljmp %3\n" +"%4:\n" +" mov a%1,%5\n" +"%3:\n" +" mov dpl,%1\n" +"%7:\n" +" mov sp,bp\n" +" pop bp\n" +"} by {\n" +" ; Peephole 103 removed redundant mov\n" +" mov dpl,%2\n" +" ljmp %3\n" +"%4:\n" +" mov dpl,%5\n" +"%3:\n" +"%7:\n" +" mov sp,bp\n" +" pop bp\n" +"}\n" +"\n" +"replace {\n" +" mov a,bp\n" +" clr c\n" +" add a,#0x01\n" +" mov r%1,a\n" +"} by {\n" +" ; Peephole 104 optimized increment (acc not set to r%1, flags undefined)\n" +" mov r%1,bp\n" +" inc r%1\n" +"}\n" +"\n" +"replace {\n" +" mov %1,a\n" +" mov a,%1\n" +"} by {\n" +" ; Peephole 105 removed redundant mov\n" +" mov %1,a\n" +"}\n" +"\n" +"replace {\n" +" mov %1,a\n" +" clr c\n" +" mov a,%1\n" +"} by {\n" +" ; Peephole 106 removed redundant mov \n" +" mov %1,a\n" +" clr c\n" +"}\n" +"\n" +"replace {\n" +" ljmp %1\n" +"%1:\n" +"} by {\n" +" ; Peephole 107 removed redundant ljmp\n" +"%1:\n" +"}\n" +"\n" +"replace {\n" +" jc %1\n" +" ljmp %5\n" +"%1:\n" +"} by {\n" +" ; Peephole 108 removed ljmp by inverse jump logic\n" +" jnc %5\n" +"%1:\n" +"} if labelInRange\n" +"\n" +"replace {\n" +" jz %1\n" +" ljmp %5\n" +"%1:\n" +"} by {\n" +" ; Peephole 109 removed ljmp by inverse jump logic\n" +" jnz %5\n" +"%1:\n" +"} if labelInRange\n" +"\n" +"replace {\n" +" jnz %1\n" +" ljmp %5\n" +"%1:\n" +"} by {\n" +" ; Peephole 110 removed ljmp by inverse jump logic\n" +" jz %5\n" +"%1:\n" +"} if labelInRange\n" +"\n" +"replace {\n" +" jb %1,%2\n" +" ljmp %5\n" +"%2:\n" +"} by {\n" +" ; Peephole 111 removed ljmp by inverse jump logic\n" +" jnb %1,%5\n" +"%2:\n" +"} if labelInRange\n" +"\n" +"replace {\n" +" jnb %1,%2\n" +" ljmp %5\n" +"%2:\n" +"} by {\n" +" ; Peephole 112 removed ljmp by inverse jump logic\n" +" jb %1,%5\n" +"%2:\n" +"} if labelInRange\n" +"\n" +"replace {\n" +" ljmp %5\n" +"%1:\n" +"} by {\n" +" ; Peephole 132 changed ljmp to sjmp\n" +" sjmp %5\n" +"%1:\n" +"} if labelInRange\n" +"\n" +"\n" +"replace {\n" +" clr a\n" +" cjne %1,%2,%3\n" +" cpl a\n" +"%3:\n" +" rrc a\n" +" mov %4,c\n" +"} by {\n" +" ; Peephole 113 optimized misc sequence\n" +" clr %4\n" +" cjne %1,%2,%3\n" +" setb %4\n" +"%3:\n" +"}\n" +"\n" +"replace {\n" +" clr a\n" +" cjne %1,%2,%3\n" +" cjne %10,%11,%3\n" +" cpl a\n" +"%3:\n" +" rrc a\n" +" mov %4,c\n" +"} by {\n" +" ; Peephole 114 optimized misc sequence\n" +" clr %4\n" +" cjne %1,%2,%3\n" +" cjne %10,%11,%3\n" +" setb %4\n" +"%3:\n" +"}\n" +"\n" +"replace {\n" +" clr a\n" +" cjne %1,%2,%3\n" +" cpl a\n" +"%3:\n" +" jnz %4\n" +"} by {\n" +" ; Peephole 115 jump optimization \n" +" cjne %1,%2,%3\n" +" sjmp %4\n" +"%3:\n" +"}\n" +"\n" +"replace {\n" +" clr a\n" +" cjne %1,%2,%3\n" +" cjne %9,%10,%3\n" +" cpl a\n" +"%3:\n" +" jnz %4\n" +"} by {\n" +" ; Peephole 116 jump optimization\n" +" cjne %1,%2,%3\n" +" cjne %9,%10,%3\n" +" sjmp %4\n" +"%3:\n" +"}\n" +"\n" +"replace {\n" +" clr a\n" +" cjne %1,%2,%3\n" +" cjne %9,%10,%3\n" +" cjne %11,%12,%3\n" +" cpl a\n" +"%3:\n" +" jnz %4\n" +"} by {\n" +" ; Peephole 117 jump optimization\n" +" cjne %1,%2,%3\n" +" cjne %9,%10,%3\n" +" cjne %11,%12,%3\n" +" sjmp %4\n" +"%3:\n" +"}\n" +"\n" +"replace {\n" +" clr a\n" +" cjne %1,%2,%3\n" +" cjne %9,%10,%3\n" +" cjne %11,%12,%3\n" +" cjne %13,%14,%3\n" +" cpl a\n" +"%3:\n" +" jnz %4\n" +"} by {\n" +" ; Peephole 118 jump optimization\n" +" cjne %1,%2,%3\n" +" cjne %9,%10,%3\n" +" cjne %11,%12,%3\n" +" cjne %13,%14,%3\n" +" sjmp %4\n" +"%3:\n" +"}\n" +"replace {\n" +" mov a,#0x01\n" +" cjne %1,%2,%3\n" +" clr a\n" +"%3:\n" +" jnz %4\n" +"} by {\n" +" ; Peephole 119 jump optimization\n" +" cjne %1,%2,%4\n" +"%3:\n" +"}\n" +"\n" +"replace {\n" +" mov a,#0x01\n" +" cjne %1,%2,%3\n" +" cjne %10,%11,%3\n" +" clr a\n" +"%3:\n" +" jnz %4\n" +"} by {\n" +" ; Peephole 120 jump optimization\n" +" cjne %1,%2,%4\n" +" cjne %10,%11,%4\n" +"%3:\n" +"}\n" +"replace {\n" +" mov a,#0x01\n" +" cjne %1,%2,%3\n" +" cjne %10,%11,%3\n" +" cjne %12,%13,%3\n" +" clr a\n" +"%3:\n" +" jnz %4\n" +"} by {\n" +" ; Peephole 121 jump optimization\n" +" cjne %1,%2,%4\n" +" cjne %10,%11,%4\n" +" cjne %12,%13,%4\n" +"%3:\n" +"}\n" +"\n" +"replace {\n" +" mov a,#0x01\n" +" cjne %1,%2,%3\n" +" cjne %10,%11,%3\n" +" cjne %12,%13,%3\n" +" cjne %14,%15,%3\n" +" clr a\n" +"%3:\n" +" jnz %4\n" +"} by {\n" +" ; Peephole 122 jump optimization\n" +" cjne %1,%2,%4\n" +" cjne %10,%11,%4\n" +" cjne %12,%13,%4\n" +" cjne %14,%15,%4\n" +"%3:\n" +"}\n" +"\n" +"replace {\n" +" mov a,#0x01\n" +" cjne %1,%2,%3\n" +" clr a\n" +"%3:\n" +" jz %4\n" +"} by {\n" +" ; Peephole 123 jump optimization\n" +" cjne %1,%2,%3\n" +" smp %4\n" +"%3:\n" +"}\n" +"replace {\n" +" mov a,#0x01\n" +" cjne %1,%2,%3\n" +" cjne %10,%11,%3\n" +" clr a\n" +"%3:\n" +" jz %4\n" +"} by {\n" +" ; Peephole 124 jump optimization\n" +" cjne %1,%2,%3\n" +" cjne %10,%11,%3\n" +" smp %4\n" +"%3:\n" +"}\n" +"\n" +"replace {\n" +" mov a,#0x01\n" +" cjne %1,%2,%3\n" +" cjne %10,%11,%3\n" +" cjne %12,%13,%3\n" +" clr a\n" +"%3:\n" +" jz %4\n" +"} by {\n" +" ; Peephole 125 jump optimization\n" +" cjne %1,%2,%3\n" +" cjne %10,%11,%3\n" +" cjne %12,%13,%3\n" +" sjmp %4\n" +"%3:\n" +"}\n" +"\n" +"replace {\n" +" mov a,#0x01\n" +" cjne %1,%2,%3\n" +" cjne %10,%11,%3\n" +" cjne %12,%13,%3\n" +" cjne %14,%15,%3\n" +" clr a\n" +"%3:\n" +" jz %4\n" +"} by {\n" +" ; Peephole 126 jump optimization\n" +" cjne %1,%2,%3\n" +" cjne %10,%11,%3\n" +" cjne %12,%13,%3\n" +" cjne %14,%15,%3\n" +" sjmp %4\n" +"%3:\n" +"}\n" +"\n" +"replace {\n" +" push psw\n" +" mov psw,%1\n" +" push bp\n" +" mov bp,%2\n" +"%3:\n" +" mov %2,bp\n" +" pop bp\n" +" pop psw\n" +" ret\n" +"} by {\n" +" ; Peephole 127 removed misc sequence\n" +" ret\n" +"}\n" +"\n" +"replace {\n" +" clr a\n" +" rlc a\n" +" jz %1\n" +"} by {\n" +" ; Peephole 128 jump optimization\n" +" jnc %1\n" +"}\n" +"\n" +"replace {\n" +" clr a\n" +" rlc a\n" +" jnz %1\n" +"} by {\n" +" ; Peephole 129 jump optimization\n" +" jc %1\n" +"}\n" +"\n" +"replace { \n" +" mov r%1,@r%2\n" +"} by {\n" +" ; Peephole 130 changed target address mode r%1 to ar%1\n" +" mov ar%1,@r%2\n" +"}\n" +"\n" +"replace { \n" +" mov a,%1\n" +" subb a,#0x01\n" +" mov %2,a\n" +" mov %1,%2\n" +"} by {\n" +" ; Peephole 131 optimized decrement (not caring for c)\n" +" dec %1 \n" +" mov %2,%1 \n" +"}\n" +"\n" +"replace {\n" +" mov r%1,%2\n" +" mov ar%3,@r%1\n" +" inc r%3\n" +" mov r%4,%2\n" +" mov @r%4,ar%3\n" +"} by {\n" +" ; Peephole 133 removed redundant moves\n" +" mov r%1,%2\n" +" inc @r%1\n" +" mov ar%3,@r%1\n" +"}\n" +"\n" +"replace {\n" +" mov r%1,%2\n" +" mov ar%3,@r%1\n" +" dec r%3\n" +" mov r%4,%2\n" +" mov @r%4,ar%3\n" +"} by {\n" +" ; Peephole 134 removed redundant moves\n" +" mov r%1,%2\n" +" dec @r%1\n" +" mov ar%3,@r%1\n" +"}\n" +"\n" +"replace {\n" +" mov r%1,a\n" +" mov a,r%2\n" +" orl a,r%1\n" +"} by {\n" +" ; Peephole 135 removed redundant mov\n" +" mov r%1,a\n" +" orl a,r%2\n" +"}\n" +"\n" +"replace {\n" +" mov %1,a\n" +" mov dpl,%2\n" +" mov dph,%3\n" +" mov dpx,%4\n" +" mov a,%1\n" +"} by {\n" +" ; Peephole 136a removed redundant moves\n" +" mov %1,a\n" +" mov dpl,%2\n" +" mov dph,%3\n" +" mov dpx,%4\n" +"} if 24bitMode\n" +"\n" +"replace {\n" +" mov %1,a\n" +" mov dpl,%2\n" +" mov dph,%3\n" +" mov a,%1\n" +"} by {\n" +" ; Peephole 136 removed redundant moves\n" +" mov %1,a\n" +" mov dpl,%2\n" +" mov dph,%3\n" +"}\n" +"\n" +"replace {\n" +" mov b,#0x00\n" +" mov a,%1\n" +" cjne %2,%3,%4\n" +" mov b,#0x01\n" +"%4:\n" +" mov a,b\n" +" jz %5\n" +"} by {\n" +" ; Peephole 137 optimized misc jump sequence\n" +" mov a,%1\n" +" cjne %2,%3,%5\n" +"%4:\n" +"}\n" +"\n" +"replace {\n" +" mov b,#0x00\n" +" mov a,%1\n" +" cjne %2,%3,%4\n" +" mov b,#0x01\n" +"%4:\n" +" mov a,b\n" +" jnz %5\n" +"} by {\n" +" ; Peephole 138 optimized misc jump sequence\n" +" mov a,%1\n" +" cjne %2,%3,%4\n" +" sjmp %5\n" +"%4:\n" +"}\n" +"\n" +"replace {\n" +" mov r%1,a\n" +" anl ar%1,%2\n" +" mov a,r%1\n" +"} by {\n" +" ; Peephole 139 removed redundant mov\n" +" anl a,%2\n" +" mov r%1,a\n" +"}\n" +"\n" +"replace {\n" +" mov r%1,a\n" +" orl ar%1,%2\n" +" mov a,r%1\n" +"} by {\n" +" ; Peephole 140 removed redundant mov\n" +" orl a,%2\n" +" mov r%1,a }\n" +"\n" +"replace {\n" +" mov r%1,a\n" +" xrl ar%1,%2\n" +" mov a,r%1\n" +"} by {\n" +" ; Peephole 141 removed redundant mov\n" +" xrl a,%2\n" +" mov r%1,a\n" +"}\n" +"\n" +"replace {\n" +" mov r%1,a\n" +" mov r%2,ar%1\n" +" mov ar%1,@r%2\n" +"} by {\n" +" ; Peephole 142 removed redundant moves\n" +" mov r%2,a\n" +" mov ar%1,@r%2\n" +"}\n" +"\n" +"replace {\n" +" rlc a\n" +" mov acc.0,c\n" +"} by {\n" +" ; Peephole 143 converted rlc to rl\n" +" rl a\n" +"}\n" +"\n" +"replace {\n" +" rrc a\n" +" mov acc.7,c\n" +"} by {\n" +" ; Peephole 144 converted rrc to rc\n" +" rr a\n" +"}\n" +"\n" +"replace {\n" +" clr c\n" +" addc a,%1\n" +"} by {\n" +" ; Peephole 145 changed to add without carry \n" +" add a,%1\n" +"}\n" +"\n" +"replace {\n" +" clr c\n" +" mov a,%1\n" +" addc a,%2\n" +"} by {\n" +" ; Peephole 146 changed to add without carry\n" +" mov a,%1\n" +" add a,%2\n" +"}\n" +"\n" +"replace {\n" +" orl r%1,a\n" +"} by {\n" +" ; Peephole 147 changed target address mode r%1 to ar%1\n" +" orl ar%1,a\n" +"}\n" +"\n" +"replace {\n" +" anl r%1,a\n" +"} by {\n" +" ; Peephole 148 changed target address mode r%1 to ar%1\n" +" anl ar%1,a\n" +"}\n" +"\n" +"replace {\n" +" xrl r%1,a\n" +"} by {\n" +" ; Peephole 149 changed target address mode r%1 to ar%1\n" +" xrl ar%1,a\n" +"}\n" +"\n" +"replace {\n" +" mov %1,dpl\n" +" mov dpl,%1\n" +"%9:\n" +" ret\n" +"} by {\n" +" ; Peephole 150 removed misc moves via dpl before return\n" +"%9:\n" +" ret\n" +"}\n" +"\n" +"replace {\n" +" mov %1,dpl\n" +" mov %2,dph\n" +" mov dpl,%1\n" +" mov dph,%2\n" +"%9:\n" +" ret\n" +"} by {\n" +" ; Peephole 151 removed misc moves via dph, dpl before return\n" +"%9:\n" +" ret\n" +"}\n" +"\n" +"replace {\n" +" mov %1,dpl\n" +" mov %2,dph\n" +" mov dpl,%1\n" +"%9:\n" +" ret\n" +"} by {\n" +" ; Peephole 152 removed misc moves via dph, dpl before return\n" +"%9:\n" +" ret\n" +"}\n" +"\n" +"replace {\n" +" mov %1,dpl\n" +" mov %2,dph\n" +" mov %3,b\n" +" mov dpl,%1\n" +" mov dph,%2\n" +" mov b,%3\n" +"%9:\n" +" ret\n" +"} by {\n" +" ; Peephole 153 removed misc moves via dph, dpl, b before return\n" +"%9:\n" +" ret\n" +"}\n" +"\n" +"replace {\n" +" mov %1,dpl\n" +" mov %2,dph\n" +" mov %3,b\n" +" mov dpl,%1\n" +"%9:\n" +" ret\n" +"} by {\n" +" ; Peephole 154 removed misc moves via dph, dpl, b before return\n" +"%9:\n" +" ret\n" +"}\n" +"\n" +"replace {\n" +" mov %1,dpl\n" +" mov %2,dph\n" +" mov %3,b\n" +" mov dpl,%1\n" +" mov dph,%2\n" +"%9:\n" +" ret\n" +"} by {\n" +" ; Peephole 155 removed misc moves via dph, dpl, b before return\n" +"%9:\n" +" ret\n" +"}\n" +"\n" +"replace {\n" +" mov %1,dpl\n" +" mov %2,dph\n" +" mov %3,b\n" +" mov %4,a\n" +" mov dpl,%1\n" +" mov dph,%2\n" +" mov b,%3\n" +" mov a,%4\n" +"%9:\n" +" ret\n" +"} by {\n" +" ; Peephole 156 removed misc moves via dph, dpl, b, a before return\n" +"%9:\n" +" ret\n" +"}\n" +"\n" +"replace {\n" +" mov %1,dpl\n" +" mov %2,dph\n" +" mov %3,b\n" +" mov %4,a\n" +" mov dpl,%1\n" +" mov dph,%2\n" +"%9:\n" +" ret\n" +"} by {\n" +" ; Peephole 157 removed misc moves via dph, dpl, b, a before return\n" +"%9:\n" +" ret\n" +"}\n" +"\n" +"replace {\n" +" mov %1,dpl\n" +" mov %2,dph\n" +" mov %3,b\n" +" mov %4,a\n" +" mov dpl,%1\n" +"%9:\n" +" ret } by {\n" +" ; Peephole 158 removed misc moves via dph, dpl, b, a before return\n" +"%9:\n" +" ret }\n" +"\n" +"replace {\n" +" mov %1,#%2\n" +" xrl %1,#0x80\n" +"} by {\n" +" ; Peephole 159 avoided xrl during execution\n" +" mov %1,#(%2 ^ 0x80)\n" +"}\n" +"\n" +"replace {\n" +" jnc %1\n" +" sjmp %2\n" +"%1:\n" +"} by {\n" +" ; Peephole 160 removed sjmp by inverse jump logic\n" +" jc %2\n" +"%1:}\n" +"\n" +"replace {\n" +" jc %1\n" +" sjmp %2\n" +"%1:\n" +"} by {\n" +" ; Peephole 161 removed sjmp by inverse jump logic\n" +" jnc %2\n" +"%1:}\n" +"\n" +"replace {\n" +" jnz %1\n" +" sjmp %2\n" +"%1:\n" +"} by {\n" +" ; Peephole 162 removed sjmp by inverse jump logic\n" +" jz %2\n" +"%1:}\n" +"\n" +"replace {\n" +" jz %1\n" +" sjmp %2\n" +"%1:\n" +"} by {\n" +" ; Peephole 163 removed sjmp by inverse jump logic\n" +" jnz %2\n" +"%1:}\n" +"\n" +"replace {\n" +" jnb %3,%1\n" +" sjmp %2\n" +"%1:\n" +"} by {\n" +" ; Peephole 164 removed sjmp by inverse jump logic\n" +" jb %3,%2\n" +"%1:\n" +"}\n" +"\n" +"replace {\n" +" jb %3,%1\n" +" sjmp %2\n" +"%1:\n" +"} by {\n" +" ; Peephole 165 removed sjmp by inverse jump logic\n" +" jnb %3,%2\n" +"%1:\n" +"}\n" +"\n" +"replace {\n" +" mov %1,%2\n" +" mov %3,%1\n" +" mov %2,%1\n" +"} by {\n" +" ; Peephole 166 removed redundant mov\n" +" mov %1,%2\n" +" mov %3,%1 }\n" +"\n" +"replace {\n" +" mov c,%1\n" +" cpl c\n" +" mov %1,c\n" +"} by {\n" +" ; Peephole 167 removed redundant bit moves (c not set to %1)\n" +" cpl %1 }\n" +"\n" +"replace {\n" +" jnb %1,%2\n" +" sjmp %3\n" +"%2:} by {\n" +" ; Peephole 168 jump optimization\n" +" jb %1,%3\n" +"%2:}\n" +"\n" +"replace {\n" +" jb %1,%2\n" +" sjmp %3\n" +"%2:} by {\n" +" ; Peephole 169 jump optimization\n" +" jnb %1,%3\n" +"%2:}\n" +"\n" +"replace {\n" +" clr a\n" +" cjne %1,%2,%3\n" +" cpl a\n" +"%3:\n" +" jz %4\n" +"} by {\n" +" ; Peephole 170 jump optimization\n" +" cjne %1,%2,%4\n" +"%3:}\n" +"\n" +"replace {\n" +" clr a\n" +" cjne %1,%2,%3\n" +" cjne %9,%10,%3\n" +" cpl a\n" +"%3:\n" +" jz %4\n" +"} by {\n" +" ; Peephole 171 jump optimization\n" +" cjne %1,%2,%4\n" +" cjne %9,%10,%4\n" +"%3:}\n" +"\n" +"replace {\n" +" clr a\n" +" cjne %1,%2,%3\n" +" cjne %9,%10,%3\n" +" cjne %11,%12,%3\n" +" cpl a\n" +"%3:\n" +" jz %4\n" +"} by {\n" +" ; Peephole 172 jump optimization\n" +" cjne %1,%2,%4\n" +" cjne %9,%10,%4\n" +" cjne %11,%12,%4\n" +"%3:}\n" +"\n" +"replace {\n" +" clr a\n" +" cjne %1,%2,%3\n" +" cjne %9,%10,%3\n" +" cjne %11,%12,%3\n" +" cjne %13,%14,%3\n" +" cpl a\n" +"%3:\n" +" jz %4\n" +"} by {\n" +" ; Peephole 173 jump optimization\n" +" cjne %1,%2,%4\n" +" cjne %9,%10,%4\n" +" cjne %11,%12,%4\n" +" cjne %13,%14,%4\n" +"%3:}\n" +"\n" +"replace {\n" +" mov r%1,%2\n" +" clr c\n" +" mov a,r%1\n" +" subb a,#0x01\n" +" mov %2,a\n" +"} by {\n" +" ; Peephole 174 optimized decrement (acc not set to %2, flags undefined)\n" +" mov r%1,%2\n" +" dec %2\n" +"}\n" +"\n" +"\n" +"replace {\n" +" mov r%1,%2\n" +" mov a,r%1\n" +" add a,#0x01\n" +" mov %2,a\n" +"} by {\n" +" ; Peephole 175 optimized increment (acc not set to %2, flags undefined)\n" +" mov r%1,%2\n" +" inc %2\n" +"}\n" +"\n" +"replace {\n" +" mov %1,@r%2\n" +" inc %1\n" +" mov @r%2,%1\n" +"} by {\n" +" ; Peephole 176 optimized increment, removed redundant mov\n" +" inc @r%2\n" +" mov %1,@r%2\n" +"}\n" +"\n" +"replace {\n" +" mov %1,%2\n" +" mov %2,%1\n" +"} by {\n" +" ; Peephole 177 removed redundant mov\n" +" mov %1,%2\n" +"}\n" +"\n" +"replace {\n" +" mov a,%1\n" +" mov b,a\n" +" mov a,%2\n" +"} by {\n" +" ; Peephole 178 removed redundant mov\n" +" mov b,%1\n" +" mov a,%2\n" +"}\n" +"\n" +"replace {\n" +" mov b,#0x00\n" +" mov a,#0x00\n" +"} by {\n" +" ; Peephole 179 changed mov to clr\n" +" clr a\n" +" mov b,a\n" +"}\n" +"\n" +"replace {\n" +" mov a,#0x00\n" +"} by {\n" +" ; Peephole 180 changed mov to clr\n" +" clr a\n" +"}\n" +"\n" +"replace {\n" +" mov dpl,#0x00\n" +" mov dph,#0x00\n" +" mov dpx,#0x00\n" +"} by {\n" +" ; Peephole 181a used 24 bit load of dptr\n" +" mov dptr,#0x0000\n" +"} if 24bitMode\n" +"\n" +"replace {\n" +" mov dpl,#0x00\n" +" mov dph,#0x00\n" +"} by {\n" +" ; Peephole 181 used 16 bit load of dptr\n" +" mov dptr,#0x0000\n" +"}\n" +"\n" +"replace {\n" +" mov dpl,#%1\n" +" mov dph,#(%1 >> 8)\n" +" mov dpx,#(%1 >> 16)\n" +"} by {\n" +" ; Peephole 182a used 24 bit load of dptr\n" +" mov dptr,#%1\n" +"} if 24bitMode\n" +"\n" +"replace {\n" +" mov dpl,#%1\n" +" mov dph,#%2\n" +"} by {\n" +" ; Peephole 182 used 16 bit load of dptr\n" +" mov dptr,#(((%2)<<8) + %1)\n" +"}\n" +"\n" +"replace {\n" +" anl %1,#%2\n" +" anl %1,#%3\n" +"} by {\n" +" ; Peephole 183 avoided anl during execution\n" +" anl %1,#(%2 & %3)\n" +"}\n" +"\n" +"replace {\n" +" mov %1,a\n" +" cpl a\n" +" mov %1,a\n" +"} by {\n" +" ; Peephole 184 removed redundant mov\n" +" cpl a\n" +" mov %1,a\n" +"}\n" +"\n" +"replace {\n" +" mov %1,a\n" +" inc %1\n" +"} by {\n" +" ; Peephole 185 changed order of increment (acc incremented also!)\n" +" inc a\n" +" mov %1,a\n" +"}\n" +"\n" +"replace {\n" +" add a,#%1\n" +" mov dpl,a\n" +" clr a\n" +" addc a,#(%1 >> 8)\n" +" mov dph,a\n" +" clr a\n" +" movc a,@a+dptr\n" +" mov %2,a\n" +" inc dptr\n" +" clr a\n" +" movc a,@a+dptr\n" +" mov %3,a\n" +" inc dptr\n" +" clr a\n" +" movc a,@a+dptr\n" +" mov %4,a\n" +" inc dptr\n" +" clr a \n" +"} by {\n" +" ; Peephole 186.a optimized movc sequence\n" +" mov dptr,#%1\n" +" mov b,acc\n" +" movc a,@a+dptr\n" +" mov %2,a\n" +" mov acc,b\n" +" inc dptr \n" +" movc a,@a+dptr\n" +" mov %3,a\n" +" mov acc,b\n" +" inc dptr\n" +" mov %4,a\n" +" mov acc,b\n" +" inc dptr\n" +"}\n" +"\n" +"replace {\n" +" add a,#%1\n" +" mov dpl,a\n" +" clr a\n" +" addc a,#(%1 >> 8)\n" +" mov dph,a\n" +" clr a\n" +" movc a,@a+dptr\n" +" mov %2,a\n" +" inc dptr\n" +" clr a\n" +" movc a,@a+dptr\n" +" mov %3,a\n" +" inc dptr\n" +" clr a\n" +"} by {\n" +" ; Peephole 186.b optimized movc sequence\n" +" mov dptr,#%1\n" +" mov b,acc\n" +" movc a,@a+dptr\n" +" mov %2,a\n" +" mov acc,b\n" +" inc dptr \n" +" movc a,@a+dptr\n" +" mov %3,a\n" +" mov acc,b\n" +" inc dptr \n" +"}\n" +"\n" +"replace {\n" +" add a,#%1\n" +" mov dpl,a\n" +" clr a\n" +" addc a,#(%1 >> 8)\n" +" mov dph,a\n" +" clr a\n" +" movc a,@a+dptr\n" +" mov %2,a\n" +" inc dptr\n" +" clr a\n" +"} by {\n" +" ; Peephole 186.c optimized movc sequence\n" +" mov dptr,#%1\n" +" mov b,acc\n" +" movc a,@a+dptr\n" +" mov %2,a\n" +" mov acc,b\n" +" inc dptr\n" +"}\n" +"\n" +"replace {\n" +" add a,#%1\n" +" mov dpl,a\n" +" clr a\n" +" addc a,#(%1 >> 8)\n" +" mov dph,a\n" +" clr a\n" +" movc a,@a+dptr\n" +"} by {\n" +" ; Peephole 186 optimized movc sequence\n" +" mov dptr,#%1\n" +" movc a,@a+dptr\n" +"}\n" +"\n" +"replace {\n" +" mov r%1,%2\n" +" anl ar%1,#%3\n" +" mov a,r%1\n" +"} by {\n" +" ; Peephole 187 used a instead of ar%1 for anl\n" +" mov a,%2\n" +" anl a,#%3\n" +" mov r%1,a\n" +"}\n" +"\n" +"replace {\n" +" mov %1,a\n" +" mov dptr,%2\n" +" movc a,@a+dptr\n" +" mov %1,a\n" +"} by {\n" +" ; Peephole 188 removed redundant mov\n" +" mov dptr,%2\n" +" movc a,@a+dptr\n" +" mov %1,a\n" +"}\n" +"\n" +"replace {\n" +" anl a,#0x0f\n" +" mov %1,a\n" +" mov a,#0x0f\n" +" anl a,%1\n" +"} by {\n" +" ; Peephole 189 removed redundant mov and anl\n" +" anl a,#0x0f\n" +" mov %1,a\n" +"}\n" +"\n" +"replace {\n" +" mov a,%1\n" +" lcall __gptrput\n" +" mov a,%1\n" +"} by {\n" +" ; Peephole 190 removed redundant mov\n" +" mov a,%1\n" +" lcall __gptrput\n" +"}\n" +"\n" +"replace {\n" +" mov %1,a\n" +" mov dpl,%2\n" +" mov dph,%3\n" +" mov b,%4\n" +" mov a,%1\n" +"} by {\n" +" ; Peephole 191 removed redundant mov\n" +" mov %1,a\n" +" mov dpl,%2\n" +" mov dph,%3\n" +" mov b,%4\n" +"}\n" +"\n" +"replace {\n" +" mov r%1,a\n" +" mov @r%2,ar%1\n" +"} by {\n" +" ; Peephole 192 used a instead of ar%1 as source\n" +" mov r%1,a\n" +" mov @r%2,a\n" +"}\n" +"\n" +"replace {\n" +" jnz %3\n" +" mov a,%4\n" +" jnz %3\n" +" mov a,%9\n" +" jnz %3\n" +" mov a,%12\n" +" cjne %13,%14,%3\n" +" sjmp %7\n" +"%3:\n" +" sjmp %8\n" +"} by {\n" +" ; Peephole 193.a optimized misc jump sequence\n" +" jnz %8\n" +" mov a,%4\n" +" jnz %8\n" +" mov a,%9\n" +" jnz %8\n" +" mov a,%12\n" +" cjne %13,%14,%8\n" +" sjmp %7\n" +"%3:\n" +"}\n" +"\n" +"replace {\n" +" cjne %1,%2,%3\n" +" mov a,%4\n" +" cjne %5,%6,%3\n" +" mov a,%9\n" +" cjne %10,%11,%3\n" +" mov a,%12\n" +" cjne %13,%14,%3\n" +" sjmp %7\n" +"%3:\n" +" sjmp %8\n" +"} by {\n" +" ; Peephole 193 optimized misc jump sequence\n" +" cjne %1,%2,%8\n" +" mov a,%4\n" +" cjne %5,%6,%8\n" +" mov a,%9\n" +" cjne %10,%11,%8\n" +" mov a,%12\n" +" cjne %13,%14,%8\n" +" sjmp %7\n" +"%3:\n" +"}\n" +"\n" +"replace {\n" +" cjne %1,%2,%3\n" +" cjne %5,%6,%3\n" +" cjne %10,%11,%3\n" +" cjne %13,%14,%3\n" +" sjmp %7\n" +"%3:\n" +" sjmp %8\n" +"} by {\n" +" ; Peephole 194 optimized misc jump sequence\n" +" cjne %1,%2,%8\n" +" cjne %5,%6,%8\n" +" cjne %10,%11,%8\n" +" cjne %13,%14,%8\n" +" sjmp %7\n" +"%3:\n" +"}\n" +"\n" +"replace {\n" +" jnz %3\n" +" mov a,%4\n" +" jnz %3\n" +" mov a,%9\n" +" cjne %10,%11,%3\n" +" sjmp %7\n" +"%3:\n" +" sjmp %8\n" +"} by {\n" +" ; Peephole 195.a optimized misc jump sequence\n" +" jnz %8\n" +" mov a,%4\n" +" jnz %8\n" +" mov a,%9\n" +" cjne %10,%11,%8\n" +" sjmp %7\n" +"%3:\n" +"}\n" +"\n" +"replace {\n" +" cjne %1,%2,%3\n" +" mov a,%4\n" +" cjne %5,%6,%3\n" +" mov a,%9\n" +" cjne %10,%11,%3\n" +" sjmp %7\n" +"%3:\n" +" sjmp %8\n" +"} by {\n" +" ; Peephole 195 optimized misc jump sequence\n" +" cjne %1,%2,%8\n" +" mov a,%4\n" +" cjne %5,%6,%8\n" +" mov a,%9\n" +" cjne %10,%11,%8\n" +" sjmp %7\n" +"%3:\n" +"}\n" +"\n" +"replace {\n" +" cjne %1,%2,%3\n" +" cjne %5,%6,%3\n" +" cjne %10,%11,%3\n" +" sjmp %7\n" +"%3:\n" +" sjmp %8\n" +"} by {\n" +" ; Peephole 196 optimized misc jump sequence\n" +" cjne %1,%2,%8\n" +" cjne %5,%6,%8\n" +" cjne %10,%11,%8\n" +" sjmp %7\n" +"%3:\n" +"}\n" +"\n" +"replace {\n" +" jnz %3\n" +" mov a,%4\n" +" cjne %5,%6,%3\n" +" sjmp %7\n" +"%3:\n" +" sjmp %8 \n" +"} by {\n" +" ; Peephole 197.a optimized misc jump sequence\n" +" jnz %8\n" +" mov a,%4\n" +" cjne %5,%6,%8\n" +" sjmp %7\n" +"%3: \n" +"}\n" +"\n" +"replace {\n" +" cjne %1,%2,%3\n" +" mov a,%4\n" +" cjne %5,%6,%3\n" +" sjmp %7\n" +"%3:\n" +" sjmp %8\n" +"} by {\n" +" ; Peephole 197 optimized misc jump sequence\n" +" cjne %1,%2,%8\n" +" mov a,%4\n" +" cjne %5,%6,%8\n" +" sjmp %7\n" +"%3:\n" +"}\n" +"\n" +"replace {\n" +" cjne %1,%2,%3\n" +" cjne %5,%6,%3\n" +" sjmp %7\n" +"%3:\n" +" sjmp %8\n" +"} by {\n" +" ; Peephole 198 optimized misc jump sequence\n" +" cjne %1,%2,%8\n" +" cjne %5,%6,%8\n" +" sjmp %7\n" +"%3:\n" +"}\n" +"\n" +"replace {\n" +" cjne %1,%2,%3\n" +" sjmp %4\n" +"%3:\n" +" sjmp %5\n" +"} by {\n" +" ; Peephole 199 optimized misc jump sequence\n" +" cjne %1,%2,%5\n" +" sjmp %4\n" +"%3:\n" +"}\n" +"\n" +"replace {\n" +" sjmp %1\n" +"%1:\n" +"} by {\n" +" ; Peephole 200 removed redundant sjmp\n" +"%1:\n" +"}\n" +"\n" +"replace {\n" +" sjmp %1\n" +"%2:\n" +"%1:\n" +"} by {\n" +" ; Peephole 201 removed redundant sjmp\n" +"%2:\n" +"%1:\n" +"}\n" +"\n" +"replace {\n" +" push acc\n" +" mov dptr,%1\n" +" pop acc\n" +"} by {\n" +" ; Peephole 202 removed redundant push pop\n" +" mov dptr,%1\n" +"}\n" +"\n" +"replace {\n" +" mov r%1,_spx\n" +" lcall %2\n" +" mov r%1,_spx\n" +"} by {\n" +" ; Peephole 203 removed mov r%1,_spx\n" +" lcall %2\n" +"}\n" +"\n" +"replace {\n" +" mov %1,a\n" +" add a,acc\n" +" mov %1,a\n" +"} by {\n" +" ; Peephole 204 removed redundant mov\n" +" add a,acc\n" +" mov %1,a\n" +"}\n" +"\n" +"replace {\n" +" djnz %1,%2\n" +" sjmp %3\n" +"%2:\n" +" sjmp %4\n" +"%3:\n" +"} by {\n" +" ; Peephole 205 optimized misc jump sequence\n" +" djnz %1,%4\n" +"%2:\n" +"%3:\n" +"}\n" +"\n" +"replace {\n" +" mov %1,%1\n" +"} by {\n" +" ; Peephole 206 removed redundant mov %1,%1\n" +"}\n" +"\n" +"replace {\n" +" mov a,_bp\n" +" add a,#0x00\n" +" mov %1,a\n" +"} by {\n" +" ; Peephole 207 removed zero add (acc not set to %1, flags undefined)\n" +" mov %1,_bp\n" +"}\n" +"\n" +"replace {\n" +" push acc\n" +" mov r%1,_bp\n" +" pop acc\n" +"} by {\n" +" ; Peephole 208 removed redundant push pop\n" +" mov r%1,_bp\n" +"}\n" +"\n" +"replace {\n" +" mov a,_bp\n" +" add a,#0x00\n" +" inc a\n" +" mov %1,a\n" +"} by {\n" +" ; Peephole 209 optimized increment (acc not set to %1, flags undefined)\n" +" mov %1,_bp\n" +" inc %1\n" +"}\n" +"\n" +"replace {\n" +" mov dptr,#((((%1 >> 16)) <<16) + (((%1 >> 8)) <<8) + %1)\n" +"} by {\n" +" ; Peephole 210a simplified expression\n" +" mov dptr,#%1\n" +"} if 24bitMode\n" +"\n" +"replace {\n" +" mov dptr,#((((%1 >> 8)) <<8) + %1)\n" +"} by {\n" +" ; Peephole 210 simplified expression\n" +" mov dptr,#%1\n" +"}\n" +"\n" +"replace {\n" +" push %1\n" +" pop %1\n" +"} by {\n" +" ; Peephole 211 removed redundant push %1 pop %1 \n" +"} \n" +"\n" +"replace {\n" +" mov a,_bp\n" +" add a,#0x01\n" +" mov r%1,a\n" +"} by {\n" +" ; Peephole 212 reduced add sequence to inc\n" +" mov r%1,_bp\n" +" inc r%1\n" +"}\n" +"\n" +"replace {\n" +" mov %1,#(( %2 >> 8 ) ^ 0x80)\n" +"} by { \n" +" mov %1,#(%2 >> 8)\n" +" xrl %1,#0x80\n" +"}\n" +"\n" +"replace {\n" +" mov %1,#(( %2 + %3 >> 8 ) ^ 0x80)\n" +"} by { \n" +" mov %1,#((%2 + %3) >> 8)\n" +" xrl %1,#0x80\n" +"}\n" +"\n" +"replace {\n" +" mov %1,a\n" +" mov a,%2\n" +" add a,%1\n" +"} by {\n" +" ; Peephole 214 reduced some extra movs\n" +" mov %1,a\n" +" add a,%2 \n" +"} if notSame(%1 %2)\n" +"\n" +"replace {\n" +" mov %1,a\n" +" add a,%2\n" +" mov %1,a\n" +"} by {\n" +" ; Peephole 215 removed some movs\n" +" add a,%2\n" +" mov %1,a\n" +"} if notSame(%1 %2)\n" +"\n" +"replace {\n" +" mov r%1,%2\n" +" clr a\n" +" inc r%1\n" +" mov @r%1,a\n" +" dec r%1\n" +" mov @r%1,a\n" +"} by {\n" +" ; Peephole 216 simplified clear (2bytes)\n" +" mov r%1,%2\n" +" clr a\n" +" mov @r%1,a\n" +" inc r%1\n" +" mov @r%1,a\n" +"}\n" +"\n" +"replace {\n" +" mov r%1,%2\n" +" clr a\n" +" inc r%1\n" +" inc r%1\n" +" mov @r%1,a\n" +" dec r%1\n" +" mov @r%1,a\n" +" dec r%1\n" +" mov @r%1,a\n" +"} by {\n" +" ; Peephole 217 simplified clear (3bytes)\n" +" mov r%1,%2\n" +" clr a\n" +" mov @r%1,a\n" +" inc r%1\n" +" mov @r%1,a\n" +" inc r%1\n" +" mov @r%1,a\n" +"}\n" +"\n" +"replace {\n" +" mov r%1,%2\n" +" clr a\n" +" inc r%1\n" +" inc r%1\n" +" inc r%1\n" +" mov @r%1,a\n" +" dec r%1\n" +" mov @r%1,a\n" +" dec r%1\n" +" mov @r%1,a\n" +" dec r%1\n" +" mov @r%1,a\n" +"} by {\n" +" ; Peephole 218 simplified clear (4bytes)\n" +" mov r%1,%2\n" +" clr a\n" +" mov @r%1,a\n" +" inc r%1\n" +" mov @r%1,a\n" +" inc r%1\n" +" mov @r%1,a\n" +" inc r%1\n" +" mov @r%1,a\n" +"}\n" +"\n" +"replace {\n" +" clr a\n" +" movx @dptr,a\n" +" mov dptr,%1\n" +" clr a\n" +" movx @dptr,a\n" +"} by {\n" +" ; Peephole 219 removed redundant clear\n" +" clr a\n" +" movx @dptr,a\n" +" mov dptr,%1\n" +" movx @dptr,a\n" +"}\n" +"\n" +"replace {\n" +" clr a\n" +" movx @dptr,a\n" +" mov dptr,%1\n" +" movx @dptr,a\n" +" mov dptr,%2\n" +" clr a\n" +" movx @dptr,a\n" +"} by {\n" +" ; Peephole 219a removed redundant clear\n" +" clr a\n" +" movx @dptr,a\n" +" mov dptr,%1\n" +" movx @dptr,a\n" +" mov dptr,%2\n" +" movx @dptr,a\n" +"}\n" diff -NaurbB sdcc-src-3.1.0/src/json/ralloc.c sdcc-src-3.1.0-pblaze/src/json/ralloc.c --- sdcc-src-3.1.0/src/json/ralloc.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/ralloc.c 2011-02-07 20:04:48.000000000 +0100 @@ -0,0 +1,259 @@ +/*------------------------------------------------------------------------ + + SDCCralloc.c - source file for register allocation. (XILINX PICOBLAZE) specific + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ + +#include "common.h" +#include "ralloc.h" +#include "gen.h" + + +extern void genJSONCode (iCode *); + +/* Global data */ +static struct { + bitVect *spiltSet; + set *stackSpil; + bitVect *regAssigned; + short blockSpil; + int slocNum; + bitVect *funcrUsed; /* registers used in a function */ + int stackExtend; + int dataExtend; +} _G; + +/* Shared with gen.c */ +int json_ptrRegReq; /* pointer register required */ + +/* JSON registers */ +regs regsJSON[] = { + {REG_GPR, S0_IDX, "s0", NULL, 0, 1}, + {REG_GPR, S1_IDX, "s1", NULL, 0, 1}, + {REG_GPR, S2_IDX, "s2", NULL, 0, 1}, + {REG_GPR, S3_IDX, "s3", NULL, 0, 1}, + {REG_GPR, S4_IDX, "s4", NULL, 0, 1}, + {REG_GPR, S5_IDX, "s5", NULL, 0, 1}, + {REG_GPR, S6_IDX, "s6", NULL, 0, 1}, + {REG_GPR, S7_IDX, "s7", NULL, 0, 1}, + {REG_GPR, S8_IDX, "s8", NULL, 0, 1}, + {REG_GPR, S9_IDX, "s9", NULL, 0, 1}, + {REG_GPR, SA_IDX, "sA", NULL, 0, 1}, + {REG_GPR, SB_IDX, "sB", NULL, 0, 1}, + {REG_GPR, SC_IDX, "sC", NULL, 0, 1}, + {REG_GPR, SD_IDX, "sD", NULL, 0, 1}, + {REG_GPR, SE_IDX, "sE", NULL, 0, 1}, + {REG_GPR, SF_IDX, "sF", NULL, 0, 1}, +}; +int json_nRegs = 16; +int json_fReg = 0; /* first allocatable register */ + + + + +/*-----------------------------------------------------------------*/ +/* json_regWithIdx - returns pointer to register with index number*/ +/*-----------------------------------------------------------------*/ +regs * +json_regWithIdx (int idx) +{ + int i; + + for (i = 0; i < json_nRegs; i++) + if (regsJSON[i].rIdx == idx) + return ®sJSON[i]; + + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "regWithIdx not found"); + exit (1); +} + +/*-----------------------------------------------------------------*/ +/* firstFreeReg - returns first free register */ +/*-----------------------------------------------------------------*/ +static regs * +firstFreeReg (void) +{ + int i; + + for (i = 0; i < json_nRegs; i++) { + if(regsJSON[i].isFree == 1) + return ®sJSON[i]; + + } + + return NULL; +} + + + +/*-----------------------------------------------------------------*/ +/* freeReg - frees a register */ +/*-----------------------------------------------------------------*/ +static void +freeReg (regs * reg) +{ + reg->isFree = 1; + reg->currSymbol = NULL; +} + + +/*-----------------------------------------------------------------*/ +/* nFreeRegs - returns number of free registers */ +/*-----------------------------------------------------------------*/ +static int +nFreeRegs (void) +{ + int i; + int nfr = 0; + + for (i = json_fReg; i < json_nRegs; i++) + if (regsJSON[i].isFree ) + nfr++; + return nfr; +} + + +/*-----------------------------------------------------------------*/ +/* isSymbolInReg - test if symbol is in registers */ +/*-----------------------------------------------------------------*/ +static int isSymbolInReg( symbol *s) +{ + int i, size, found = 0; + + if(!s) + return 0; + + + size = getSize ( s->type ); + + + // && s->regs[ regsJSON[i].offset ] == ®sJSON[i] + + + for (i = json_fReg; i < json_nRegs; i++) + { + if (regsJSON[i].currSymbol == s ) { + found++; + } + + } + + if (found == size) return 1; + else if (found == 0) return 0; + + wassertl(FALSE, "chybi cast operandu v registrech"); +} + + +/*-----------------------------------------------------------------*/ +/* assignReg - assign registers to the symbol */ +/*-----------------------------------------------------------------*/ +void +XXXassignReg (operand * op) +{ + regs *rtmp; + int i, size; + + // Q? pouze typ Symbol + if(op->type == SYMBOL) { + + /* get number of requied registers */ + size = getSize ( operandType (op) ); + //size = OP_SYMBOL(op)->nRegs; + + /* symbol is already in the registers */ + if ( isSymbolInReg( OP_SYMBOL(op) ) ) { + + + } + + + /* symbol is not in the registers and there is a sufficient number of registers for assigment */ + else if (nFreeRegs() >= size) { + + //printf("Size:%d\n", size); + + OP_SYMBOL(op)->nRegs = size; + + for(i = 0; i<size; i++) { + + rtmp = firstFreeReg(); + if(!rtmp) assert ("neosetreno\n"); + + rtmp->isFree = 0; + rtmp->currSymbol = OP_SYMBOL(op); + rtmp->offset = i; + + OP_SYMBOL(op)->regs[i] = rtmp; + + } + + } + + // TODO: nedostatek registru, + // Q?: potreba uvolnit -> pamet / zasobnik + else { + + + + } + + } +} + + + +/*-----------------------------------------------------------------*/ +/* assignRegisters */ +/*-----------------------------------------------------------------*/ +void +json_assignRegisters (ebbIndex * ebbi) +{ + eBBlock ** ebbs = ebbi->bbOrder; + int count = ebbi->count; + iCode *ic; + int i; + + setToNull ((void *) &_G.funcrUsed); + //json_ptrRegReq = _G.stackExtend = _G.dataExtend = 0; + + + + /* now get back the chain */ + //ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count)); + + //symbol *sym, *tempsym; + //sym = (symbol *) findSymWithLevel(SymbolTab,tempsym); + //printf("sym:%s\n", SymbolTab[0]->name); + + + ic = iCodeFromeBBlock (ebbs, count); + + genJSONCode (ic); + /* for (; ic ; ic = ic->next) */ + /* piCode(ic,stdout); */ + /* free up any _G.stackSpil locations allocated */ + + _G.slocNum = 0; + + /* mark all registers as free */ + + return; +} diff -NaurbB sdcc-src-3.1.0/src/json/ralloc.h sdcc-src-3.1.0-pblaze/src/json/ralloc.h --- sdcc-src-3.1.0/src/json/ralloc.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/json/ralloc.h 2011-02-07 20:04:44.000000000 +0100 @@ -0,0 +1,58 @@ +/*------------------------------------------------------------------------- + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ +#ifndef _JSON_SDCCRALLOC_H +#define _JSON_SDCCRALLOC_H + +#include "SDCCicode.h" +#include "SDCCBBlock.h" + + +enum + { + S0_IDX = 0, + S1_IDX, S2_IDX, S3_IDX, S4_IDX, + S5_IDX, S6_IDX, S7_IDX, S8_IDX, + S9_IDX, SA_IDX, SB_IDX, SC_IDX, + SD_IDX, SE_IDX, SF_IDX + }; + + +#define REG_PTR 0x01 +#define REG_GPR 0x02 /* general purpose registers*/ + + +/* definition for the registers */ +typedef struct regs + { + short type; /* PicoBlaze have only REG_GPR */ + short rIdx; /* index into register table */ + char *name; /* name */ + symbol *currSymbol; /* current symbol in the register */ + short offset; /* offset of the operand (if larger than 1B) */ + unsigned isFree:1; /* is currently unassigned */ + } +regs; +extern regs regsJSON[]; + +//void assignReg (operand * op); + +regs *json_regWithIdx (int); + +#endif diff -NaurbB sdcc-src-3.1.0/src/pblaze/Makefile.in sdcc-src-3.1.0-pblaze/src/pblaze/Makefile.in --- sdcc-src-3.1.0/src/pblaze/Makefile.in 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/pblaze/Makefile.in 2011-08-23 15:56:30.000000000 +0200 @@ -0,0 +1,8 @@ +VPATH = @srcdir@ +srcdir = @srcdir@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +# Make all in this directory +include $(srcdir)/../port.mk + diff -NaurbB sdcc-src-3.1.0/src/pblaze/gen.c sdcc-src-3.1.0-pblaze/src/pblaze/gen.c --- sdcc-src-3.1.0/src/pblaze/gen.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/pblaze/gen.c 2011-12-05 23:53:59.470216200 +0100 @@ -0,0 +1,3628 @@ +/*------------------------------------------------------------------------- +gen.c - source file for code generation for XILINX PICOBLAZE + +Author: + Jakub Hornik, xhorni00<at>stud.fit.vutbr.cz +Master Thesis Project: + Compiler Back-End of Subset of Language C for 8-Bit Processor +Date: + 2011 + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +In other words, you are welcome to use, share and improve this program. +You are forbidden to forbid anyone else to use, share and improve +what you give them. Help stamp out software-hoarding! + + +-------------------------------------------------------------------------*/ + +#define D(x) do if (options.verboseAsm) {x;} while(0) +#define LBL_KEY(x) x->key+100 + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include "SDCCglobl.h" +#include "newalloc.h" + +#include "common.h" +#include "SDCCpeeph.h" +#include "ralloc.h" +#include "gen.h" + +static struct { + short onStack; + short inLine; + short debugLine; + short isCalleSaves; + short ptrOff; + set *sendSet; + set *inOutSet; + bitVect *rUsedVect; + iCode *current_iCode; +} _G; + + +static struct { + short mschar; + short muschar; + short mint; + short mlong; + short dschar; + short duschar; + short modschar; + short moduschar; + short dsint; + short dusint; + short modsint; + short modusint; + short dslong; + short duslong; + short modslong; + short moduslong; +} _GFunc; + +extern int allocInfo; +extern int pblaze_ptrRegReq; +extern int pblaze_nRegs; +extern struct dbuf_s *codeOutBuf; + +/* function return value registers - shared with send/receive */ +char *fReturnPBLAZE[] = { "sB", "sC", "sD", "sE" }; + +unsigned fPBLAZEReturnSize = 4; /* shared with ralloc.c */ +char **fPBLAZEReturn = fReturnPBLAZE; +char buffValP[64]; +char *buffVal = buffValP; + +static lineNode *lineHead = NULL; +static lineNode *lineCurr = NULL; + +static int recvCnt = 0; +short initGen = 0; + +/*-----------------------------------------------------------------*/ +/* pblaze_emitcode - writes the code into a file */ +/*-----------------------------------------------------------------*/ +static void pblaze_emitcode(char *inst, char *fmt, ...) +{ + va_list ap; + char lb[INITIAL_INLINEASM]; + char *lbp = lb; + + va_start(ap, fmt); + + if (inst && *inst) { + if (fmt && *fmt) + sprintf(lb, "%s\t", inst); + else + sprintf(lb, "%s", inst); + vsprintf(lb + (strlen(lb)), fmt, ap); + } else + vsprintf(lb, fmt, ap); + + while (isspace((unsigned char) *lbp)) + lbp++; + + if (lbp && *lbp) + lineCurr = (lineCurr ? connectLine(lineCurr, newLineNode(lb)) : (lineHead = newLineNode(lb))); + lineCurr->isInline = _G.inLine; + lineCurr->isDebug = _G.debugLine; + lineCurr->ic = _G.current_iCode; + va_end(ap); +} + +/*-----------------------------------------------------------------*/ +/* dialectNum-convert a number to a string with the correct dialect */ +/*-----------------------------------------------------------------*/ +char *dialectNum(int num) +{ + char *s = buffVal; + sprintf(s, "%s%02x", pblaze_options.dialect ? "" : "$", num); + return Safe_strdup(s); +} + + +/*-----------------------------------------------------------------*/ +/* addInOutRef - mark oper as IN/OUT pointer with given offset */ +/*-----------------------------------------------------------------*/ +void addInOutRef(operand * oper, operand * offset) +{ + unsigned long lit = 0L; + inOutStruct_t *tmpInOut = Safe_alloc(sizeof(inOutStruct_t)); + + tmpInOut->name = Safe_strdup(OP_SYMBOL(oper)->name); + tmpInOut->tempOper = oper; + tmpInOut->liveFrom = OP_LIVEFROM(oper); + tmpInOut->liveTo = OP_LIVETO(oper); + + if (!offset) { + tmpInOut->isNumOffset = 1; + tmpInOut->regOffset = NULL; + tmpInOut->numOffset = 0L; + + } else if (isOperandLiteral(offset)) { + lit = ulFromVal(OP_VALUE(offset)); + tmpInOut->isNumOffset = 1; + tmpInOut->regOffset = NULL; + tmpInOut->numOffset = lit; + } else { + tmpInOut->isNumOffset = 0; + tmpInOut->regOffset = offset; + } + addSet(&_G.inOutSet, tmpInOut); +} + +/*-----------------------------------------------------------------*/ +/* isInOutRef - test if the given operand is a IN/OUT pointer */ +/*-----------------------------------------------------------------*/ +int isInOutRef(operand * oper) +{ + char *name = OP_SYMBOL(oper)->name; + if (strcmp(pblaze_options.portKw, name) == 0) + return 1; + + set *lp; + + for (lp = _G.inOutSet; lp; lp = lp->next) { + inOutStruct_t *p = lp->item; + if (strcmp(p->name, name) == 0) + return 1; + } + return 0; +} + +/*-----------------------------------------------------------------*/ +/* getInOutRef - return io struct of the given operand */ +/*-----------------------------------------------------------------*/ +inOutStruct_t *getInOutRef(operand * oper) +{ + char *name = OP_SYMBOL(oper)->name; + set *lp; + + for (lp = _G.inOutSet; lp; lp = lp->next) { + inOutStruct_t *p = lp->item; + if (strcmp(p->name, name) == 0) + break; + } + if (!lp) + return NULL; + + return lp->item; +} + +/*-------------------------------------------------------------------------*/ +/* pblaze_emitcodeOutput - emit OUTPUT instruction with given params */ +/*-------------------------------------------------------------------------*/ +void pblaze_emitcodeOutputNum(char *l, char *r) +{ + if (pblaze_options.dialect) + pblaze_emitcode("OUTPUT", "%s, %s", l, r); + else + pblaze_emitcode("OUT", "%s, %s", l, r); +} + +/*-------------------------------------------------------------------------*/ +/* pblaze_emitcodeOutput - emit OUTPUT instruction with given params */ +/*-------------------------------------------------------------------------*/ +void pblaze_emitcodeOutputReg(char *l, char *r) +{ + if (pblaze_options.dialect) + pblaze_emitcode("OUTPUT", "%s, (%s)", l, r); + else + pblaze_emitcode("OUT", "%s, %s", l, r); +} + +/*-------------------------------------------------------------------------*/ +/* pblaze_emitcodeOutput - emit OUTPUT instruction with given params */ +/*-------------------------------------------------------------------------*/ +void pblaze_emitcodeOutput(iCode * ic, char *source, operand * to) +{ + inOutStruct_t *tmp; + tmp = getInOutRef(to); + + if (!tmp) { + return; + } else if (tmp->isNumOffset) { + pblaze_emitcodeOutputNum(source, dialectNum((int) tmp->numOffset)); + } else { + pblaze_emitcodeOutputReg(source, aopGetRegName(ic, tmp->regOffset, 0)); + } +} + +/*-------------------------------------------------------------------------*/ +/* pblaze_emitcodeInputNum - emit INPUT instruction with given params */ +/*-------------------------------------------------------------------------*/ +void pblaze_emitcodeInputNum(char *l, char *r) +{ + if (pblaze_options.dialect) + pblaze_emitcode("INPUT", "%s, %s", l, r); + else + pblaze_emitcode("IN", "%s, %s", l, r); +} + +/*-------------------------------------------------------------------------*/ +/* pblaze_emitcodeInputReg - emit INPUT instruction with given params */ +/*-------------------------------------------------------------------------*/ +void pblaze_emitcodeInputReg(char *l, char *r) +{ + if (pblaze_options.dialect) + pblaze_emitcode("INPUT", "%s, (%s)", l, r); + else + pblaze_emitcode("IN", "%s, %s", l, r); +} + +/*-----------------------------------------------------------------*/ +/* pblaze_emitcodeInput - emit INPUT instruction with given params */ +/*-----------------------------------------------------------------*/ +void pblaze_emitcodeInput(iCode * ic, operand * result, int resOffset, operand * from) +{ + inOutStruct_t *tmp; + tmp = getInOutRef(from); + + if (!tmp) { + return; + } else if (tmp->isNumOffset) { + pblaze_emitcodeInputNum(aopGetRegName(ic, result, resOffset), dialectNum((int) tmp->numOffset)); + } else { + pblaze_emitcodeInputReg(aopGetRegName(ic, result, resOffset), aopGetRegName(ic, tmp->regOffset, 0)); + } +} + + +/*-----------------------------------------------------------------*/ +/* emit functions */ +/*-----------------------------------------------------------------*/ +void pblaze_emitLabel(symbol * tlbl) +{ + pblaze_emitcode("", "_L%05d:", LBL_KEY(tlbl)); + lineCurr->isLabel = 1; +} + +void pblaze_emitLabelC(symbol * tlbl) +{ + pblaze_emitcode("", "_LC%05d:", LBL_KEY(tlbl)); + lineCurr->isLabel = 1; +} + +void pblaze_emitcodeADDCY(char *l, char *r) +{ + if (pblaze_options.dialect) + pblaze_emitcode("ADDCY", "%s, %s", l, r); + else + pblaze_emitcode("ADDC", "%s, %s", l, r); +} + +void pblaze_emitcodeSUBCY(char *l, char *r) +{ + if (pblaze_options.dialect) + pblaze_emitcode("SUBCY", "%s, %s", l, r); + else + pblaze_emitcode("SUBC", "%s, %s", l, r); +} + +void pblaze_emitcodeCompare(char *l, char *r) +{ + if (pblaze_options.dialect) + pblaze_emitcode("COMPARE", "%s, %s", l, r); + else + pblaze_emitcode("COMP", "%s, %s", l, r); +} + +void pblaze_emitcodeStore(char *l, char *r) +{ + if (pblaze_options.dialect && r[0] == 's') + pblaze_emitcode("STORE", "%s, (%s)", l, r); + else + pblaze_emitcode("STORE", "%s, %s", l, r); +} + +void pblaze_emitcodeFetch(char *l, char *r) +{ + if (pblaze_options.dialect && r[0] == 's') + pblaze_emitcode("FETCH", "%s, (%s)", l, r); + else + pblaze_emitcode("FETCH", "%s, %s", l, r); +} + +/*-----------------------------------------------------------------*/ +/* isOpVolatile - test if operand is volatile */ +/*-----------------------------------------------------------------*/ +int isOpVolatile(operand * oper) +{ + sym_link *type, *search; + if (!oper || oper->type != SYMBOL || OP_LIVETO(oper) != 0) + return 0; + + if (operandType(oper)) { + for (type = operandType(oper); type && type->next; type = type->next); + + while (type) { + + if (IS_DECL(type) && DCL_PTR_VOLATILE(type)) + return 2; + + else if (!IS_DECL(type) && SPEC_VOLATILE(type)) + return 1; + + for (search = operandType(oper); search && search->next != type;) + search = search->next; + type = search; + } + + } + return 0; +} + +// debug, test +void testOp(operand * oper) +{ + if (isOperandLiteral(oper)) { + return; + } + printf("%s, rname:%s\t", OP_SYMBOL(oper)->name, OP_SYMBOL(oper)->rname); + if (IS_OP_VOLATILE(oper)) { + printf(" volatile, "); + } + + if (oper->isaddr) { + printf(" adress, "); + } + + if (IS_OP_GLOBAL(oper)) { + printf(" global, "); + } + + if (IS_OP_POINTER(oper)) { + printf(" pointer, "); + } + + if (IS_OP_PARM(oper)) { + printf(" parm, "); + } + + if (IS_ITEMP(oper)) { + printf(" itemp, "); + } + + if (IS_PTR(OP_SYMBOL(oper)->type)) { + printf(" is_ptr, "); + } + + if (IS_VOLATILE(OP_SYMBOL(oper)->type)) { + printf(" is_volatile, "); + } + + if (IS_CODE(OP_SYMBOL(oper)->type)) { + printf(" is_code, "); + } + + if (IS_ABSOLUTE(OP_SYMBOL(oper)->type)) { + printf(" is_absolute, "); + } + + if (IS_REGISTER(OP_SYMBOL(oper)->type)) { + printf(" is_register, "); + } + + if (IS_STATIC(OP_SYMBOL(oper)->type)) { + printf(" is_static, "); + } + + if (IS_SYMOP(oper) && IS_ARRAY(OP_SYM_TYPE(oper))) { + printf(" is_array, "); + } + + if (IS_SYMOP(oper) && IS_STRUCT(OP_SYM_TYPE(oper))) { + printf(" is_struct, "); + } + + if (IS_SYMOP(oper) && IS_TYPEDEF(OP_SYM_TYPE(oper))) { + printf(" is_typedef, "); + } + + if (isOpVolatile(oper)) + printf(" isvolatile, "); + + printf("\n"); + +} + + +/*-----------------------------------------------------------------*/ +/* pblaze_emitDebuggerSymbol - associate the current code location */ +/* with a debugger symbol */ +/*-----------------------------------------------------------------*/ +void pblaze_emitDebuggerSymbol(const char *debugSym) +{ + _G.debugLine = 1; + pblaze_emitcode("", "%s ==.", debugSym); + _G.debugLine = 0; +} + + +/*-----------------------------------------------------------------*/ +/* valueOffset */ +/*-----------------------------------------------------------------*/ +unsigned int valueOffset(unsigned long lit, int offset) +{ + return ((lit >> (offset * 8)) & 0x0FFL); +} + + +/*-----------------------------------------------------------------*/ +/* emit STORE and FETCH functions */ +/*-----------------------------------------------------------------*/ +void emitStore(char *r, int mem) +{ + char *s; + s = operName(mem); + if (!s) + pblaze_emitcode("STORE", "%s, %s%02x", r, pblaze_options.dialect ? "" : "$", mem); + else + pblaze_emitcode("STORE", "%s, %s", r, s); +} + +void emitStoreReg(char *r, char *adr) +{ + if (pblaze_options.dialect) + pblaze_emitcode("STORE", "%s, (%s)", r, adr); + else + pblaze_emitcode("STORE", "%s, %s", r, adr); +} + +void emitFetch(char *r, int mem) +{ + char *s; + s = operName(mem); + if (!s) + pblaze_emitcode("FETCH", "%s, %s%02x", r, pblaze_options.dialect ? "" : "$", mem); + else + pblaze_emitcode("FETCH", "%s, %s", r, s); +} + +void emitLoadNumb(char *r, int val) +{ + pblaze_emitcode("LOAD", "%s, %s%02x", r, pblaze_options.dialect ? "" : "$", val); +} + +void emitLoad(char *l, char *r) +{ + pblaze_emitcode("LOAD", "%s, %s", l, r); +} + +void emitcodeADD(char *l, int val) +{ + pblaze_emitcode("ADD", "%s, %s%02x", l, pblaze_options.dialect ? "" : "$", val); +} + +void emitcodeSUB(char *l, int val) +{ + pblaze_emitcode("SUB", "%s, %s%02x", l, pblaze_options.dialect ? "" : "$", val); +} + + + +/*-----------------------------------------------------------------*/ +/* bitVect functions */ +/*-----------------------------------------------------------------*/ +void setRegUsed(int r) +{ + bitVectSetBit(_G.rUsedVect, r); +} + +int isRegUsed(int r) +{ + return bitVectBitValue(_G.rUsedVect, r); +} + +void clearBitVect(bitVect * bv) +{ + int i; + for (i = 0; i < bv->size; i++) + bitVectUnSetBit(bv, i); +} + +short isCalleesaves(void) +{ + return _G.isCalleSaves; +} + + + + + +/*-----------------------------------------------------------------*/ +/* Push given register onto the stack */ +/*-----------------------------------------------------------------*/ +void pushStack(int rdx, int c) +{ + reg_info *rStack; + rStack = pblaze_regWithIdx(rdx); + pblaze_emitcodeStore(rStack->name, "sF"); + pblaze_emitcode("SUB", "sF, %s", dialectNum(1)); + + _G.onStack++; + + staticMemoryCheck(MEMSIZE - _G.onStack - 1); +} + +/*-----------------------------------------------------------------*/ +/* Pop top of the the stack into given register */ +/*-----------------------------------------------------------------*/ +void popStack(int rdx, int c) +{ + reg_info *rStack; + rStack = pblaze_regWithIdx(rdx); + + pblaze_emitcode("ADD", "sF, %s", dialectNum(1)); + pblaze_emitcodeFetch(rStack->name, "sF"); + + _G.onStack--; + staticMemoryCheck(MEMSIZE - _G.onStack - 1); +} + + +/*-----------------------------------------------------------------*/ +/* regsInCommon - two operands have some registers in common */ +/*-----------------------------------------------------------------*/ +static bool regsInCommon(operand * op1, operand * op2) +{ + symbol *sym1, *sym2; + int i; + + /* if they have registers in common */ + if (!IS_SYMOP(op1) || !IS_SYMOP(op2)) + return FALSE; + + sym1 = OP_SYMBOL(op1); + sym2 = OP_SYMBOL(op2); + + if (sym1->nRegs == 0 || sym2->nRegs == 0) + return FALSE; + + for (i = 0; i < sym1->nRegs; i++) { + int j; + if (!sym1->regs[i]) + continue; + + for (j = 0; j < sym2->nRegs; j++) { + if (!sym2->regs[j]) + continue; + + if (sym2->regs[j] == sym1->regs[i]) + return TRUE; + } + } + + return FALSE; +} + +/*-----------------------------------------------------------------*/ +/* pblaze_operandsEqu - equivalent */ +/*-----------------------------------------------------------------*/ +bool pblaze_operandsEqu(operand * op1, operand * op2) +{ + symbol *sym1, *sym2; + + /* if they not symbols */ + if (!IS_SYMOP(op1) || !IS_SYMOP(op2)) + return FALSE; + + sym1 = OP_SYMBOL(op1); + sym2 = OP_SYMBOL(op2); + + /* if they are the same */ + if (sym1 == sym2) + return TRUE; + + if (strcmp(sym1->rname, sym2->rname) == 0) + return TRUE; + + + /* if left is a tmp & right is not */ + if (IS_ITEMP(op1) && !IS_ITEMP(op2) && sym1->isspilt && (sym1->usl.spillLoc == sym2)) + return TRUE; + + if (IS_ITEMP(op2) && !IS_ITEMP(op1) && sym2->isspilt && sym1->level > 0 && (sym2->usl.spillLoc == sym1)) + return TRUE; + + return FALSE; +} + +/*-----------------------------------------------------------------*/ +/* pointerSetOpt - optimization of assigning a value via a pointer */ +/*-----------------------------------------------------------------*/ +int pointerSetOpt(iCode * ic, int currOffset) +{ + iCode *aic, *pic, *lic; + int pOffset, nOffset; + + if (!POINTER_SET(ic)) + return 0; + + if (!ic->next || !ic->next->next || !ic->prev) + return 0; + + aic = ic->next; + pic = aic->next; + lic = ic->prev; + + /* previous offset of the pointer */ + if (pblaze_operandsEqu(IC_RESULT(ic), IC_RESULT(lic)) && OP_LIVETO(IC_RESULT(ic)) == ic->seq) { + if (lic->op == '+' && isOperandLiteral(IC_RIGHT(lic))) { + pOffset = (int) ulFromVal(OP_VALUE(IC_RIGHT(lic))); + } else if (lic->op == ADDRESS_OF) + pOffset = 0; + else + return 0; + } else + return 0; + + /* next offset of the pointer */ + if (aic->op == '+' && POINTER_SET(pic) && pblaze_operandsEqu(IC_RESULT(aic), IC_RESULT(pic)) + && OP_LIVETO(IC_RESULT(pic)) == ic->seq + 2) { + if (isOperandLiteral(IC_RIGHT(aic))) { + nOffset = (int) ulFromVal(OP_VALUE(IC_RIGHT(aic))); + } else + return 0; + } else + return 0; + + /* set pointer to the correct location */ + assignOpt(ic, IC_RESULT(aic), IC_RESULT(ic)); + pblaze_emitcode("ADD", "%s, %s", aopGetRegName(ic, IC_RESULT(aic), 0), dialectNum(nOffset - pOffset - currOffset)); + aopUpdateOpInMem(ic, IC_RESULT(aic), 0); + /* set next ADD instruction as generated */ + aic->generated = 1; + + return 1; +} + +/*-----------------------------------------------------------------*/ +/* Copy registers */ +/*-----------------------------------------------------------------*/ +void copyRegisters(iCode * ic, operand * opTo, operand * opFrom, int rFrom, int rTo) +{ + int i; + int sizeT = getSize(operandType(opTo)); + + for (i = rFrom; i <= rTo; i++) { + aopPutReg(ic, opTo, aopGetReg(ic, opFrom, i), i); + } + for (; i < sizeT; i++) { + aopPutVal(ic, opTo, dialectNum(0), i); + } +} + +/*-----------------------------------------------------------------*/ +/* pblaze_assignResultValue - */ +/*-----------------------------------------------------------------*/ +void pblaze_assignResultValue(iCode * ic, operand * oper) +{ + int i = 0; + int size = getSize(operandType(oper)); + while (size--) { + aopPutVal(ic, oper, fPBLAZEReturn[i], i); + i++; + } +} + +/*-----------------------------------------------------------------*/ +/* assignLiteral - */ +/*-----------------------------------------------------------------*/ +void assignLiteral(operand * result, operand * literal, iCode * ic) +{ + int size, sizeR; + unsigned long lit = 0L; + int i; + + /* is a literal value */ + if (isOperandLiteral(literal)) { + /* get value and size */ + lit = ulFromVal(OP_VALUE(literal)); + size = getSize(operandType(literal)); + sizeR = getSize(operandType(result)); + //size = sizeR > size ? size : sizeR; + + if (IS_OP_GLOBAL(result)) { + for (i = 0; i < size; i++) { + aopPutVal(ic, result, dialectNum(valueOffset(lit, i)), i); + } + } + + else if (POINTER_SET(ic)) { + + if(isInOutRef(result) ){ + aopPutVal(ic, result, dialectNum(valueOffset(lit, 0)), 0); + return; + } + + for (i = 0; i < size; i++) { + aopPutVal(ic, result, dialectNum(valueOffset(lit, size - i - 1)), i); + + if (i + 1 < size) { + pblaze_emitcode("ADD", "%s, %s", aopGetRegName(ic, result, 0), dialectNum(1)); + aopUpdateOpInMem(ic, result, 0); + } + } + /* pointer will be used later, return to the begining */ + if (!pointerSetOpt(ic, size - 1) && size > 1 && OP_LIVETO(result) > ic->seq) { + pblaze_emitcode("SUB", "%s, %s", aopGetRegName(ic, result, 0), dialectNum(size - 1)); + aopUpdateOpInMem(ic, result, 0); + } + } else { + for (i = 0; i < size; i++) { + aopPutVal(ic, result, dialectNum(valueOffset(lit, i)), i); + } + } + } + +} + + +/*-----------------------------------------------------------------*/ +/* assignLiteralRegs - */ +/*-----------------------------------------------------------------*/ +void assignLiteralRegs(int size, char **regs, operand * literal) +{ + unsigned long lit = 0L; + int i; + + /* is a literal value */ + if (isOperandLiteral(literal)) { + + /* get value and size */ + lit = ulFromVal(OP_VALUE(literal)); + + for (i = size - 1; i >= 0; i--) { + pblaze_emitcode("LOAD", "%s, %s", regs[i], dialectNum(valueOffset(lit, i))); + } + } +} + + + +/*-----------------------------------------------------------------*/ +/* toBoolean - emit code for comparision */ +/*-----------------------------------------------------------------*/ +reg_info *toBoolean(iCode * ic, operand * oper) +{ + int size = getSize(operandType(oper)); + int offset = 1; + reg_info *r; + + if (size == 1) { + return aopGetReg(ic, oper, 0); + } + + else { + r = getReg(ic); + lockReg(r); + pblaze_emitcode("LOAD", "%s, %s", r->name, aopGetRegName(ic, oper, 0)); + + while (--size) { + pblaze_emitcode("OR", "%s, %s", r->name, aopGetRegName(ic, oper, offset)); + offset++; + } + unlockReg(r); + } + return r; +} + +/*-----------------------------------------------------------------*/ +/* genNot - generate code for ! operation */ +/*-----------------------------------------------------------------*/ +static void genNot(iCode * ic) +{ + operand *result, *left; + reg_info *r; + D(pblaze_emitcode(";", "genNot")); + + symbol *lbl = newiTempLabel(NULL); + + result = IC_RESULT(ic); + left = IC_LEFT(ic); + + /* fill the result with zeros */ + aopPutVal(ic, result, dialectNum(0), 0); + + r = toBoolean(ic, left); + pblaze_emitcodeCompare(r->name, dialectNum(0)); + pblaze_emitcode("JUMP", "NZ, _LC%05d", LBL_KEY(lbl)); + aopPutVal(ic, result, dialectNum(1), 0); + pblaze_emitLabelC(lbl); +} + + + + +/*-----------------------------------------------------------------*/ +/* genCpl - generate code for complement */ +/*-----------------------------------------------------------------*/ +static void genCpl(iCode * ic) +{ + int offset = 0; + int size; + operand *result, *left; + + D(pblaze_emitcode(";", "genCpl")); + + result = IC_RESULT(ic); + left = IC_LEFT(ic); + size = getSize(operandType(result)); + + /* the right symbol may ends at this position */ + if (ASSIGN_OPT(result, left) && assignOptTest(ic, IC_RESULT(ic))) { + assignOpt(ic, result, left); + } else { + copyRegisters(ic, result, left, 0, size - 1); + } + + while (size--) { + pblaze_emitcode("XOR", "%s, %s", aopGetRegName(ic, result, offset), dialectNum(255)); + aopUpdateOpInMem(ic, result, offset); + offset++; + } + +} + +/*-----------------------------------------------------------------*/ +/* genUminus - unary minus code generation */ +/*-----------------------------------------------------------------*/ +static void genUminus(iCode * ic) +{ + operand *result, *left; + int i, size; + + D(pblaze_emitcode(";", "genUminus")); + + result = IC_RESULT(ic); + left = IC_LEFT(ic); + size = getSize(operandType(result)); + + /* right symbol may ends at this position */ + if (ASSIGN_OPT(result, left) && assignOptTest(ic, IC_RESULT(ic))) { + assignOpt(ic, result, left); + } else { + copyRegisters(ic, result, left, 0, size - 1); + } + + /* invert bytes */ + for (i = 0; i < size; i++) { + pblaze_emitcode("XOR", "%s, %s", aopGetRegName(ic, result, i), dialectNum(255)); + aopUpdateOpInMem(ic, result, i); + } + + /* add one */ + pblaze_emitcode("ADD", "%s, %s", aopGetRegName(ic, result, 0), dialectNum(1)); + aopUpdateOpInMem(ic, result, 0); + for (i = 1; i < size; i++) { + pblaze_emitcodeADDCY(aopGetRegName(ic, result, i), dialectNum(0)); + aopUpdateOpInMem(ic, result, i); + } + +} + +/*-----------------------------------------------------------------*/ +/* genIpush - genrate code for pushing */ +/*-----------------------------------------------------------------*/ +static void genIpush(iCode * ic) +{ + operand *left; + int offset, size; + unsigned long lit = 0L; + reg_info *r; + offset = 0; + + left = IC_LEFT(ic); + size = getSize(operandType(left)); + + D(pblaze_emitcode(";", "genIpush")); + if (isOperandLiteral(left)) { + + /* get value */ + lit = ulFromVal(OP_VALUE(left)); + /* needs to be loaded into registers first -> get a free register */ + r = getReg(ic); + + while (size--) { + /* first load into registers */ + pblaze_emitcode("LOAD", "%s, %s", r->name, dialectNum((unsigned int) ((lit >> (offset++ * 8)) & 0x0FFL))); + /* push onto the stack */ + pushStack(r->rIdx, 1); + } + + } else { + + while (size--) { + pushStack(aopGetReg(ic, left, offset)->rIdx, 1); + offset++; + } + } + +} + +/*-----------------------------------------------------------------*/ +/* genIpop - recover the registers */ +/*-----------------------------------------------------------------*/ +static void genIpop(iCode * ic) +{ + operand *left; + int offset, size; + + left = IC_LEFT(ic); + size = getSize(operandType(left)); + offset = size - 1; + + D(pblaze_emitcode(";", "genIpop")); + + if (isOperandLiteral(left)) { + return; + } + + while (size--) { + popStack(aopGetReg(ic, left, offset)->rIdx, 1); + offset--; + } +} + + +/*-----------------------------------------------------------------*/ +/* testFuncCall - check whether it should called the MUL or DIV func*/ +/*-----------------------------------------------------------------*/ +int testFuncCall(char *name) +{ + int start = S0_IDX; + + /* test if it is a mult or div function call */ + if (strcmp(name, MULUSCHAR) == 0) { + _GFunc.muschar = 1; + start = SB_IDX; + } else if (strcmp(name, MULSCHAR) == 0) { + _GFunc.mschar = 1; + _GFunc.muschar = 1; + start = SA_IDX; + } else if (strcmp(name, MULINT) == 0) { + _GFunc.mint = 1; + start = S7_IDX; + } else if (strcmp(name, MULLONG) == 0) { + _GFunc.mlong = 1; + start = S2_IDX; + } else if (strcmp(name, DIVSCHAR) == 0) { + _GFunc.dschar = 1; + _GFunc.duschar = 1; + start = SA_IDX; + } else if (strcmp(name, DIVUSCHAR) == 0) { + _GFunc.duschar = 1; + start = SB_IDX; + } else if (strcmp(name, DIVSINT) == 0) { + _GFunc.dsint = 1; + _GFunc.dusint = 1; + start = S7_IDX; + } else if (strcmp(name, DIVUSINT) == 0) { + _GFunc.dusint = 1; + start = S7_IDX; + } else if (strcmp(name, DIVSLONG) == 0) { + _GFunc.dslong = 1; + _GFunc.duslong = 1; + start = S2_IDX; + } else if (strcmp(name, DIVUSLONG) == 0) { + _GFunc.duslong = 1; + start = S2_IDX; + } else if (strcmp(name, MODSCHAR) == 0) { + _GFunc.modschar = 1; + _GFunc.dschar = 1; + _GFunc.duschar = 1; + start = SA_IDX; + } else if (strcmp(name, MODUSCHAR) == 0) { + _GFunc.moduschar = 1; + _GFunc.duschar = 1; + start = SB_IDX; + } else if (strcmp(name, "_moduschar") == 0) { + _GFunc.moduschar = 1; + _GFunc.duschar = 1; + start = SB_IDX; + } else if (strcmp(name, MODSINT) == 0) { + _GFunc.modsint = 1; + _GFunc.dsint = 1; + _GFunc.dusint = 1; + start = S7_IDX; + } else if (strcmp(name, MODUSINT) == 0) { + _GFunc.modusint = 1; + _GFunc.dusint = 1; + start = S7_IDX; + } else if (strcmp(name, MODSLONG) == 0) { + _GFunc.modslong = 1; + _GFunc.dslong = 1; + _GFunc.duslong = 1; + start = S2_IDX; + } else if (strcmp(name, MODUSLONG) == 0) { + _GFunc.moduslong = 1; + _GFunc.duslong = 1; + start = S2_IDX; + } + + return start; +} + +/*-----------------------------------------------------------------*/ +/* genCall - generates a call statement */ +/*-----------------------------------------------------------------*/ +static void genCall(iCode * ic) +{ + int i, j; + int size; + reg_info *r; + operand *sOp; + iCode *sic; + int rmax = SEND_REG_COUNT; + int rfrst = SEND_REG_FIRST; + int saveFrom; + bitVect *rSaved; + unsigned long lit = 0L; + + D(pblaze_emitcode(";", "genCall")); + + /* store globals. if changed */ + freeGlobalsFromReg(); + + rSaved = newBitVect(pblaze_nRegs); + + /* test if its a multiply, div or mod call */ + saveFrom = testFuncCall(OP_SYMBOL(IC_LEFT(ic))->name); + + /* caller-saves, push used registers onto the stack */ + if (!_G.isCalleSaves && !IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type)) { + for (i = S0_IDX; i <= SF_IDX; i++) { + r = pblaze_regWithIdx(i); + if (i >= saveFrom && r->isFree == 0 && r->isReserved == 0 && r->currOper + && OP_LIVETO(r->currOper) > ic->seq) { + pushStack(i, 1); + // noted that the registers were moved to the stack + bitVectSetBit(rSaved, i); + } else if (i >= saveFrom && isOpVolatile(r->currOper) && !IS_OP_GLOBAL(r->currOper)) { + pushStack(i, 1); + bitVectSetBit(rSaved, i); + } else + bitVectUnSetBit(rSaved, i); + } + } + ///////////////////////////////////////////////////// + + /* if send set is not empty then assign */ + if (_G.sendSet) { + D(pblaze_emitcode(";", "genSend")); + _G.sendSet = reverseSet(_G.sendSet); + // through all + for (sic = setFirstItem(_G.sendSet); sic; sic = setNextItem(_G.sendSet)) { + sOp = IC_LEFT(sic); + size = getSize(operandType(sOp)); + + // enough free registers for SEND + if (size <= rmax) { + rmax -= size; + + /* send operand is value */ + if (isOperandLiteral(sOp)) { + /* get value */ + lit = ulFromVal(OP_VALUE(sOp)); + /* needs to be loaded into registers first */ + for (j = 0; j < size; j++) { + pblaze_emitcode("LOAD", "%s, %s", pblaze_regWithIdx(rfrst)->name, + dialectNum((unsigned int) ((lit >> ((j) * 8)) & 0x0FFL))); + rfrst++; + } + } + + /* send operand is symbol */ + else { + + for (i = 0; i < size; i++) { + pblaze_emitcode("LOAD", "%s, %s", pblaze_regWithIdx(rfrst)->name, aopGetRegName(sic, sOp, i)); + rfrst++; + } + } + /* not enought free registers -> use stack */ + } else { + /* send operand is value */ + if (isOperandLiteral(sOp)) { + reg_info *r; + + /* get value */ + lit = ulFromVal(OP_VALUE(sOp)); + /* needs to be loaded into registers first -> get a free register */ + r = getReg(ic); + + for (j = 0; j < size; j++) { + /* first load into a register */ + pblaze_emitcode("LOAD", "%s, %s", r->name, + dialectNum((unsigned int) ((lit >> (j * 8)) & 0x0FFL))); + /* push onto the stack */ + pushStack(r->rIdx, 1); + } + } + /* send operand is symbol */ + else { + + for (i = 0; i < size; i++) { + /* push onto the stack */ + if (aopGetReg(sic, sOp, i)) { + pushStack(OP_SYMBOL(sOp)->regs[i]->rIdx, 1);; + } + } + + } + _G.onStack -= (size - 1); + + } + } + _G.sendSet = NULL; + } + /////////////////////////////////////////////////////////////////// + + /* make the call */ + pblaze_emitcode("CALL", "%s", + (OP_SYMBOL(IC_LEFT(ic))->rname[0] ? OP_SYMBOL(IC_LEFT(ic))->rname : OP_SYMBOL(IC_LEFT(ic))->name)); + + /* test if it is a mult or div function call */ + if (strcmp(OP_SYMBOL(IC_LEFT(ic))->name, MULUSCHAR) == 0) + _GFunc.muschar = 1; + if (strcmp(OP_SYMBOL(IC_LEFT(ic))->name, MULSCHAR) == 0) { + _GFunc.mschar = 1; + _GFunc.muschar = 1; + } + if (strcmp(OP_SYMBOL(IC_LEFT(ic))->name, MULINT) == 0) + _GFunc.mint = 1; + if (strcmp(OP_SYMBOL(IC_LEFT(ic))->name, MULLONG) == 0) + _GFunc.mlong = 1; + + if (strcmp(OP_SYMBOL(IC_LEFT(ic))->name, DIVSCHAR) == 0) { + _GFunc.dschar = 1; + _GFunc.duschar = 1; + } + if (strcmp(OP_SYMBOL(IC_LEFT(ic))->name, DIVUSCHAR) == 0) + _GFunc.duschar = 1; + if (strcmp(OP_SYMBOL(IC_LEFT(ic))->name, MODSCHAR) == 0) { + _GFunc.modschar = 1; + _GFunc.dschar = 1; + _GFunc.duschar = 1; + } + if (strcmp(OP_SYMBOL(IC_LEFT(ic))->name, MODUSCHAR) == 0) { + _GFunc.moduschar = 1; + _GFunc.duschar = 1; + } + if (strcmp(OP_SYMBOL(IC_LEFT(ic))->name, "_moduschar") == 0) { + _GFunc.moduschar = 1; + _GFunc.duschar = 1; + } + + /* pop used registers into the registers */ + if (!_G.isCalleSaves && !IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type)) { + for (i = SF_IDX; i >= S0_IDX; i--) { + r = pblaze_regWithIdx(i); + if (bitVectBitValue(rSaved, i)) { + popStack(i, 1); + } + } + } + + /* if we need assign a result value */ + if (IS_ITEMP(IC_RESULT(ic)) && OP_SYMBOL(IC_RESULT(ic))->liveTo > ic->seq) { + pblaze_assignResultValue(ic, IC_RESULT(ic)); + + } + +} + +/*-----------------------------------------------------------------*/ +/* genPcall - generates a call by pointer statement */ +/*-----------------------------------------------------------------*/ +static void genPcall(iCode * ic) +{ + /* not easy to implement without access to the Instruction pointer */ + fprintf(stderr, "%s:%d: pblaze port error: function pointers are not supported\n", __FILE__, __LINE__); + exit(1); +} + + +/*-----------------------------------------------------------------*/ +/* genFunction - generated code for function entry */ +/*-----------------------------------------------------------------*/ +static void genFunction(iCode * ic) +{ + symbol *sym; + sym_link *ftype; + + sym = OP_SYMBOL(IC_LEFT(ic)); + + /* create the function header */ + D(pblaze_emitcode(";", "-----------------------------------------")); + D(pblaze_emitcode(";", " function %s", sym->name)); + D(pblaze_emitcode(";", "-----------------------------------------")); + + pblaze_emitcode("", "%s:", sym->rname); + lineCurr->isLabel = 1; + ftype = operandType(IC_LEFT(ic)); + + if (IFFUNC_CALLEESAVES(sym->type)) { + _G.isCalleSaves = 1; + } + + /* is an interrupt function */ + if (IFFUNC_ISISR(sym->type)) { + + if (!pblaze_interrupt) + pblaze_interrupt = sym; + else if (FUNC_INTNO(sym->type) > FUNC_INTNO(pblaze_interrupt->type)) + pblaze_interrupt = sym; + + _G.isCalleSaves = 1; + } + + /* if critical function then turn interrupts off */ + if (IFFUNC_ISCRITICAL(ftype)) { + if (pblaze_options.dialect) { + pblaze_emitcode("DISABLE INTERRUPT", ""); + } else { + pblaze_emitcode("DINT", ""); + } + } +} + +/*-----------------------------------------------------------------*/ +/* genEndFunction - generates epilogue for functions */ +/*-----------------------------------------------------------------*/ +static void genEndFunction(iCode * ic) +{ + int i; + + D(pblaze_emitcode(";", "genEndFunction")); + + symbol *sym = OP_SYMBOL(IC_LEFT(ic)); + + _G.isCalleSaves = 0; + + /* interrupt routine or callee saves - pop saved registers back */ + if (IFFUNC_ISISR(sym->type) || IFFUNC_CALLEESAVES(sym->type)) { + + for (i = pblaze_nRegs - 1; i >= 0; i--) { + if (bitVectBitValue(_G.rUsedVect, i)) + popStack(i, 0); + } + clearBitVect(_G.rUsedVect); + } + + /* store globals. if changed */ + freeGlobalsFromReg(); + + if (options.debug && currFunc) { + debugFile->writeEndFunction(currFunc, ic, 1); + } + + if (pblaze_options.dialect) { + if (IFFUNC_ISCRITICAL(sym->type)) + pblaze_emitcode("ENABLE INTERRUPT", ""); + + if (IFFUNC_ISISR(sym->type)) { + pblaze_emitcode("RETURNI ENABLE", ""); + } else { + pblaze_emitcode("RETURN", ""); + } + } else { + if (IFFUNC_ISCRITICAL(sym->type)) + pblaze_emitcode("EINT", ""); + + if (IFFUNC_ISISR(sym->type)) { + pblaze_emitcode("RETI ENABLE", ""); + } else { + pblaze_emitcode("RET", ""); + } + + } + // clear + clearMemEndFunc(); +} + +/*-----------------------------------------------------------------*/ +/* genRet - generate code for return statement */ +/*-----------------------------------------------------------------*/ +static void genRet(iCode * ic) +{ + int size, i; + operand *left; + char *s; + + D(pblaze_emitcode(";", "genRet")); + + /* we have something to return then move the return value into place */ + if (IC_LEFT(ic)) { + left = IC_LEFT(ic); + size = getSize(operandType(left)); + + if (isOperandLiteral(left)) { + assignLiteralRegs(size, fPBLAZEReturn, left); + } else { + for (i = size - 1; i >= 0; i--) { + s = aopGetRegName(ic, left, i); + if (strcmp(s, fPBLAZEReturn[i]) != 0) + pblaze_emitcode("LOAD", "%s, %s", fPBLAZEReturn[i], s); + } + } + } + + /* + if (!(ic->next && ic->next->op == LABEL && + IC_LABEL (ic->next) == returnLabel)) + + pblaze_emitcode ("JUMP", "_L%05d", LBL_KEY(returnLabel) ); + */ +} + +/*-----------------------------------------------------------------*/ +/* genLabel - generates a label */ +/*-----------------------------------------------------------------*/ +static void genLabel(iCode * ic) +{ + if (strcmp(IC_LABEL(ic)->name, entryLabel->name) == 0) + return; + + pblaze_emitLabel(IC_LABEL(ic)); +} + +/*-----------------------------------------------------------------*/ +/* genGoto - generates a jmp */ +/*-----------------------------------------------------------------*/ +static void genGoto(iCode * ic) +{ + D(pblaze_emitcode(";", "genGoto")); + pblaze_emitcode("JUMP", "_L%05d", LBL_KEY(IC_LABEL(ic))); +} + + +/*-----------------------------------------------------------------*/ +/* genPlus - generates code for addition */ +/*-----------------------------------------------------------------*/ +static void genPlus(iCode * ic) +{ + if (isInOutRef(IC_LEFT(ic))) { + addInOutRef(IC_RESULT(ic), IC_RIGHT(ic)); + return; + } + + int size, sizeL; + int i; + bool swappedLR = FALSE, loadOpt = FALSE; + unsigned long lit = 0L; + operand *leftOp, *rightOp, *result; + int optim = 0; + + D(pblaze_emitcode(";", "genPlus")); + + /* optimize assigment before adding */ + if (ic->next && ic->next->op == '=' && !isOperandLiteral(IC_LEFT(ic)) && OP_LIVETO(IC_RESULT(ic)) == ic->next->seq + && pblaze_operandsEqu(IC_RESULT(ic), IC_RIGHT(ic->next)) + && pblaze_operandsEqu(IC_LEFT(ic), IC_RESULT(ic->next))) { + IC_RESULT(ic) = IC_LEFT(ic); + ic->next->generated = 1; + optim = 1; + } else if (ic->next && ic->next->op == '=' && !isOperandLiteral(IC_RIGHT(ic)) + && OP_LIVETO(IC_RESULT(ic)) == ic->next->seq && pblaze_operandsEqu(IC_RESULT(ic), IC_RIGHT(ic->next)) + && pblaze_operandsEqu(IC_RIGHT(ic), IC_RESULT(ic->next))) { + operand *t = IC_RIGHT(ic); + IC_RIGHT(ic) = IC_LEFT(ic); + IC_LEFT(ic) = t; + IC_RESULT(ic) = IC_LEFT(ic); + ic->next->generated = 1; + optim = 1; + } else if (isOperandLiteral(IC_LEFT(ic)) || pblaze_operandsEqu(IC_RESULT(ic), IC_RIGHT(ic)) || + (IC_LEFT(ic)->type == SYMBOL && !isOpInReg(IC_LEFT(ic)) && IC_RIGHT(ic)->type == SYMBOL + && isOpInReg(IC_RIGHT(ic))) || (IS_OP_GLOBAL(IC_LEFT(ic)) && !IS_OP_GLOBAL(IC_RIGHT(ic)) + && !isOperandLiteral(IC_RIGHT(ic)))) { + operand *t = IC_RIGHT(ic); + IC_RIGHT(ic) = IC_LEFT(ic); + IC_LEFT(ic) = t; + swappedLR = TRUE; + } + + result = IC_RESULT(ic); + rightOp = IC_RIGHT(ic); + leftOp = IC_LEFT(ic); + + + /* left and result operands aren't the same */ + if (!pblaze_operandsEqu(IC_RESULT(ic), IC_LEFT(ic))) { + + /* assign optimalization (left symbol may ends at this position) */ + if (ASSIGN_OPT(result, leftOp)) { + assignOpt(ic, result, leftOp); + loadOpt = TRUE; + } + + sizeL = getSize(operandType(leftOp)); + size = getSize(operandType(result)); + + if (!loadOpt) { + copyRegisters(ic, result, leftOp, 0, size - 1); + } + + } + + /* right operand is value */ + if (isOperandLiteral(rightOp)) { + + /* get value and size */ + lit = ulFromVal(OP_VALUE(rightOp)); + size = getSize(operandType(result)); + + pblaze_emitcode("ADD", "%s, %s", aopGetRegName(ic, result, 0), dialectNum(valueOffset(lit, 0))); + aopUpdateOpInMem(ic, result, 0); + for (i = 1; i < size; i++) { + pblaze_emitcodeADDCY(aopGetRegName(ic, result, i), dialectNum(valueOffset(lit, i))); + aopUpdateOpInMem(ic, result, i); + } + } + + /* right operand is symbol */ + else if (OP_SYMBOL(rightOp)) { + + size = getSize(operandType(result)); + sizeL = getSize(operandType(rightOp)); + + pblaze_emitcode("ADD", "%s, %s", aopGetRegName(ic, result, 0), aopGetRegName(ic, rightOp, 0)); + aopUpdateOpInMem(ic, result, 0); + for (i = 1; i < size; i++) { + if (i < sizeL) { + pblaze_emitcodeADDCY(aopGetRegName(ic, result, i), aopGetRegName(ic, rightOp, i)); + aopUpdateOpInMem(ic, result, i); + } else { + pblaze_emitcodeADDCY(aopGetRegName(ic, result, i), dialectNum(0)); + aopUpdateOpInMem(ic, result, i); + } + } + + } + if (optim && IS_OP_GLOBAL(result)) + globalChanged(result, IN_REG); + +} + +/*-----------------------------------------------------------------*/ +/* genMinus - generates code for subtraction */ +/*-----------------------------------------------------------------*/ +static void genMinus(iCode * ic) +{ + if (isInOutRef(IC_LEFT(ic))) { + addInOutRef(IC_RESULT(ic), IC_RIGHT(ic)); + return; + } + + operand *leftOp, *rightOp, *result; + int i, size, sizeR; + unsigned long lit = 0L; + + D(pblaze_emitcode(";", "genMinus")); + + if (ic->next && ic->next->op == '=' && !isOperandLiteral(IC_LEFT(ic)) && OP_LIVETO(IC_RESULT(ic)) == ic->next->seq + && pblaze_operandsEqu(IC_RESULT(ic), IC_RIGHT(ic->next)) + && pblaze_operandsEqu(IC_LEFT(ic), IC_RESULT(ic->next))) { + IC_RESULT(ic) = IC_LEFT(ic); + ic->next->generated = 1; + } + + result = IC_RESULT(ic); + rightOp = IC_RIGHT(ic); + leftOp = IC_LEFT(ic); + size = getSize(operandType(result)); + + /* left and result operands aren't the same */ + if (!pblaze_operandsEqu(IC_RESULT(ic), IC_LEFT(ic))) { + /* left operand is a literal */ + if (isOperandLiteral(leftOp)) { + assignLiteral(result, leftOp, ic); + } + + /* assign optimalization (left symbol may ends at this position) */ + else if (ASSIGN_OPT(result, leftOp)) { + assignOpt(ic, result, leftOp); + } + /* copy left operand into result operand */ + else { + copyRegisters(ic, result, leftOp, 0, size - 1); + } + } + + /* right operand is a value */ + if (isOperandLiteral(rightOp)) { + + /* get value and size */ + lit = ulFromVal(OP_VALUE(rightOp)); + size = getSize(operandType(result)); + + pblaze_emitcode("SUB", "%s, %s", aopGetRegName(ic, result, 0), dialectNum(valueOffset(lit, 0))); + aopUpdateOpInMem(ic, result, 0); + for (i = 1; i < size; i++) { + pblaze_emitcodeSUBCY(aopGetRegName(ic, result, i), dialectNum(valueOffset(lit, i))); + aopUpdateOpInMem(ic, result, i); + } + } + + /* right operand is a symbol */ + else if (OP_SYMBOL(rightOp)) { + + size = getSize(operandType(result)); + sizeR = getSize(operandType(rightOp)); + + pblaze_emitcode("SUB", "%s, %s", aopGetRegName(ic, result, 0), aopGetRegName(ic, rightOp, 0)); + aopUpdateOpInMem(ic, result, 0); + for (i = 1; i < size; i++) { + if (i < sizeR) { + pblaze_emitcodeSUBCY(aopGetRegName(ic, result, i), aopGetRegName(ic, rightOp, i)); + aopUpdateOpInMem(ic, result, i); + } else { + pblaze_emitcodeSUBCY(aopGetRegName(ic, result, i), dialectNum(0)); + aopUpdateOpInMem(ic, result, i); + } + } + } +} + + +/*-----------------------------------------------------------------*/ +/* genMult - generates code for multiplication */ +/*-----------------------------------------------------------------*/ +static void genMult(iCode * ic) +{ + /* should have been converted to function call */ + assert(0); +} + + + +/*-----------------------------------------------------------------*/ +/* genDiv - generates code for division */ +/*-----------------------------------------------------------------*/ +static void genDiv(iCode * ic) +{ + /* should have been converted to function call */ + assert(0); +} + +/*-----------------------------------------------------------------*/ +/* genMod - generates code for division */ +/*-----------------------------------------------------------------*/ +static void genMod(iCode * ic) +{ + /* should have been converted to function call */ + assert(0); + +} + + + +/*-----------------------------------------------------------------*/ +/* genMulDivFunc - generates function for multiply and division */ +/*-----------------------------------------------------------------*/ +void genMulDivFunc(FILE * of) +{ + if (_GFunc.mschar) + genMultChar(of); + if (_GFunc.muschar) + genMultUnsignedChar(of); + if (_GFunc.mint) + genMultInt(of); + if (_GFunc.mlong) + genMultLong(of); + + if (_GFunc.modschar) + genModChar(of); + if (_GFunc.moduschar) + genModUnsignedChar(of); + if (_GFunc.dschar) + genDivChar(of); + if (_GFunc.duschar) + genDivUnsignedChar(of); + + if (_GFunc.modsint) + genModInt(of); + if (_GFunc.modusint) + genModUnsignedInt(of); + if (_GFunc.dsint) + genDivInt(of); + if (_GFunc.dusint) + genDivUnsignedInt(of); + + if (_GFunc.modslong) + genModLong(of); + if (_GFunc.moduslong) + genModUnsignedLong(of); + if (_GFunc.dslong) + genDivLong(of); + if (_GFunc.duslong) + genDivUnsignedLong(of); +} + + +/*-----------------------------------------------------------------*/ +/* genCmp - compare left < right */ +/*-----------------------------------------------------------------*/ +static void genCmp(iCode * ic, operand * left, operand * right, operand * result, iCode * ifx) +{ + int size; + unsigned long lit = 0L; + value *aop_lit = NULL; + symbol *lblo, *lble; + + D(pblaze_emitcode(";", "genCompare")); + + size = max(getSize(operandType(left)), getSize(operandType(right))); + + /* next operation is IFX */ + if (ifx) { + /* right operand is a literal value */ + if (isOperandLiteral(right)) { + /* get value and size */ + lit = ulFromVal(OP_VALUE(right)); + + /* true label will be generated */ + if (IC_TRUE(ifx)) { + + while (size--) { + pblaze_emitcodeCompare(aopGetRegName(ic, left, size), dialectNum(valueOffset(lit, size))); + pblaze_emitcode("JUMP", "C, _L%05d", LBL_KEY(IC_TRUE(ifx))); + } + } + + /* false label will be generated */ + else { + lble = newiTempLabel(NULL); + + while (size--) { + pblaze_emitcodeCompare(aopGetRegName(ic, left, size), dialectNum(valueOffset(lit, size))); + pblaze_emitcode("JUMP", "C, _LC%05d", LBL_KEY(lble)); + } + + pblaze_emitcode("JUMP", "_L%05d", LBL_KEY(IC_FALSE(ifx))); + pblaze_emitLabelC(lble); + } + } + /* left operand is a literal value */ + else if (isOperandLiteral(left)) { + reg_info *reg; + aop_lit = OP_VALUE(left); + reg = getReg(ic); + lockReg(reg); + /* get value and size */ + lit = ulFromVal(aop_lit); + + /* true label will be generated */ + if (IC_TRUE(ifx)) { + while (size--) { + pblaze_emitcode("LOAD", "%s, %s", reg->name, dialectNum(valueOffset(lit, size))); + pblaze_emitcodeCompare(reg->name, aopGetRegName(ic, right, size)); + pblaze_emitcode("JUMP", "C, _L%05d", LBL_KEY(IC_TRUE(ifx))); + } + } + + /* false label will be generated */ + else { + lble = newiTempLabel(NULL); + + while (size--) { + pblaze_emitcode("LOAD", "%s, %s", reg->name, dialectNum(valueOffset(lit, size))); + pblaze_emitcodeCompare(reg->name, aopGetRegName(ic, right, size)); + pblaze_emitcode("JUMP", "C, _LC%05d", LBL_KEY(lble)); + } + + pblaze_emitcode("JUMP", "_L%05d", LBL_KEY(IC_FALSE(ifx))); + pblaze_emitLabelC(lble); + } + unlockReg(reg); + } + /* both are in the registers */ + else { + /* true label will be generated */ + if (IC_TRUE(ifx)) { + + while (size--) { + pblaze_emitcodeCompare(aopGetRegName(ic, left, size), aopGetRegName(ic, right, size)); + pblaze_emitcode("JUMP", "C, _L%05d", LBL_KEY(IC_TRUE(ifx))); + } + + } + /* false label will be generated */ + else { + lble = newiTempLabel(NULL); + + while (size--) { + pblaze_emitcodeCompare(aopGetRegName(ic, left, size), aopGetRegName(ic, right, size)); + pblaze_emitcode("JUMP", "C, _LC%05d", LBL_KEY(lble)); + } + + pblaze_emitcode("JUMP", "_L%05d", LBL_KEY(IC_FALSE(ifx))); + pblaze_emitLabelC(lble); + } + } + + ifx->generated = 1; + + } + /* next instruction is not IFX */ + else { + + aopPutVal(ic, result, dialectNum(0), 0); + + if (size == 1) { + + if (isOperandLiteral(right)) + aop_lit = OP_VALUE(right); + if (isOperandLiteral(left)) + aop_lit = OP_VALUE(left); + + lit = ulFromVal(aop_lit); + + /* right side is a literal value */ + if (isOperandLiteral(right)) + pblaze_emitcodeCompare(aopGetRegName(ic, left, 0), dialectNum(valueOffset(lit, 0))); + + /* left side is a literal value */ + else if (isOperandLiteral(left)) { + reg_info *reg; + reg = getReg(ic); + lockReg(reg); + pblaze_emitcode("LOAD", "%s, %s", reg->name, dialectNum(valueOffset(lit, 0))); + pblaze_emitcodeCompare(reg->name, aopGetRegName(ic, right, 0)); + unlockReg(reg); + } else + pblaze_emitcodeCompare(aopGetRegName(ic, left, 0), aopGetRegName(ic, right, 0)); + + pblaze_emitcodeADDCY(aopGetRegName(ic, result, 0), dialectNum(0)); + aopUpdateOpInMem(ic, result, 0); + } else { + /* right side is a literal value */ + if (isOperandLiteral(right)) { + + lblo = newiTempLabel(NULL); + lble = newiTempLabel(NULL); + + /* get value and size */ + lit = ulFromVal(OP_VALUE(right)); + + while (size--) { + pblaze_emitcodeCompare(aopGetRegName(ic, left, size), dialectNum(valueOffset(lit, size))); + pblaze_emitcode("JUMP", "C, _LC%05d", LBL_KEY(lblo)); + } + + pblaze_emitcode("JUMP", "_LC%05d", LBL_KEY(lble)); + pblaze_emitLabelC(lblo); + + aopPutVal(ic, result, dialectNum(1), 0); + pblaze_emitLabelC(lble); + } + /* left side is a literal value */ + else if (isOperandLiteral(left)) { + reg_info *reg; + lblo = newiTempLabel(NULL); + lble = newiTempLabel(NULL); + aop_lit = OP_VALUE(left); + reg = getReg(ic); + lockReg(reg); + /* get value and size */ + lit = ulFromVal(aop_lit); + + while (size--) { + pblaze_emitcode("LOAD", "%s, %s", reg->name, dialectNum(valueOffset(lit, size))); + pblaze_emitcodeCompare(reg->name, aopGetRegName(ic, right, size)); + pblaze_emitcode("JUMP", "C, _LC%05d", LBL_KEY(lblo)); + } + unlockReg(reg); + + pblaze_emitcode("JUMP", "_LC%05d", LBL_KEY(lble)); + pblaze_emitLabelC(lblo); + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 0), dialectNum(1)); + aopUpdateOpInMem(ic, result, 0); + pblaze_emitLabelC(lble); + + + } else { + lblo = newiTempLabel(NULL); + lble = newiTempLabel(NULL); + + while (size--) { + pblaze_emitcodeCompare(aopGetRegName(ic, left, size), aopGetRegName(ic, right, size)); + pblaze_emitcode("JUMP", "C, _LC%05d", LBL_KEY(lblo)); + } + + pblaze_emitcode("JUMP", "_LC%05d", LBL_KEY(lble)); + pblaze_emitLabelC(lblo); + + aopPutVal(ic, result, dialectNum(1), 0); + pblaze_emitLabelC(lble); + + } + } + } +} + +/*-----------------------------------------------------------------*/ +/* genCmpGt :- greater than comparison */ +/*-----------------------------------------------------------------*/ +static void genCmpGt(iCode * ic, iCode * ifx) +{ + operand *left, *right, *result; + + D(pblaze_emitcode(";", "genCmpGt")); + + left = IC_LEFT(ic); + right = IC_RIGHT(ic); + result = IC_RESULT(ic); + + genCmp(ic, right, left, result, ifx); +} + +/*-----------------------------------------------------------------*/ +/* genCmpLt - less than comparisons */ +/*-----------------------------------------------------------------*/ +static void genCmpLt(iCode * ic, iCode * ifx) +{ + operand *left, *right, *result; + + D(pblaze_emitcode(";", "genCmpLt")); + + left = IC_LEFT(ic); + right = IC_RIGHT(ic); + result = IC_RESULT(ic); + + genCmp(ic, left, right, result, ifx); +} + +/*-----------------------------------------------------------------*/ +/* genCmpEq - generates code for equal to */ +/*-----------------------------------------------------------------*/ +static void genCmpEq(iCode * ic, iCode * ifx) +{ + operand *left, *right, *result; + int size, sizeL, sizeR, offset = 0; + + D(pblaze_emitcode(";", "genCmpEq")); + + + if (isOperandLiteral(IC_LEFT(ic)) && !isOperandLiteral(IC_RIGHT(ic))) { + operand *t = IC_RIGHT(ic); + IC_RIGHT(ic) = IC_LEFT(ic); + IC_LEFT(ic) = t; + } + + left = IC_LEFT(ic); + right = IC_RIGHT(ic); + result = IC_RESULT(ic); + + sizeL = getSize(operandType(left)); + sizeR = getSize(operandType(right)); + size = max(sizeL, sizeR); + + /* next operation is IFX */ + if (ifx) { + /* true label exists */ + if (IC_TRUE(ifx)) { + + symbol *lblfl = newiTempLabel(NULL); + /* right operand is a literal */ + if (isOperandLiteral(right)) { + unsigned long lit = ulFromVal(OP_VALUE(right)); + + while (size--) { + pblaze_emitcodeCompare(aopGetRegName(ic, left, offset), dialectNum(valueOffset(lit, offset))); + pblaze_emitcode("JUMP", "NZ, _LC%05d", LBL_KEY(lblfl)); + offset++; + } + + pblaze_emitcode("JUMP", "_L%05d", LBL_KEY(IC_TRUE(ifx))); + + pblaze_emitLabelC(lblfl); + } + + /* right operand is in the registers */ + else { + while (size--) { + pblaze_emitcodeCompare(aopGetRegName(ic, left, offset), aopGetRegName(ic, right, offset)); + pblaze_emitcode("JUMP", "NZ, _LC%05d", LBL_KEY(lblfl)); + offset++; + } + + pblaze_emitcode("JUMP", "_L%05d", LBL_KEY(IC_TRUE(ifx))); + + pblaze_emitLabelC(lblfl); + } + } + + /* false label exists */ + else { + /* right operand is a literal */ + if (isOperandLiteral(right)) { + unsigned long lit = ulFromVal(OP_VALUE(right)); + + while (size--) { + pblaze_emitcodeCompare(aopGetRegName(ic, left, offset), dialectNum(valueOffset(lit, offset))); + pblaze_emitcode("JUMP", "NZ, _L%05d", LBL_KEY(IC_FALSE(ifx))); + offset++; + } + } + + /* right operand is in the registers */ + else { + + while (size--) { + pblaze_emitcodeCompare(aopGetRegName(ic, left, offset), aopGetRegName(ic, right, offset)); + pblaze_emitcode("JUMP", "NZ, _L%05d", LBL_KEY(IC_FALSE(ifx))); + offset++; + } + } + } + ifx->generated = 1; + } + + /* next operation is not IFX */ + else { + symbol *lblfl = newiTempLabel(NULL); + + /* right operand is a literal */ + if (isOperandLiteral(right)) { + unsigned long lit = ulFromVal(OP_VALUE(right)); + + aopPutVal(ic, result, dialectNum(0), 0); + + while (size--) { + pblaze_emitcodeCompare(aopGetRegName(ic, left, offset), dialectNum(valueOffset(lit, offset))); + pblaze_emitcode("JUMP", "NZ, _LC%05d", LBL_KEY(lblfl)); + offset++; + } + + aopPutVal(ic, result, dialectNum(1), 0); + pblaze_emitLabelC(lblfl); + } + + /* right operand is in the registers */ + else { + aopPutVal(ic, result, dialectNum(0), 0); + + while (size--) { + pblaze_emitcodeCompare(aopGetRegName(ic, left, offset), aopGetRegName(ic, right, offset)); + pblaze_emitcode("JUMP", "NZ, _LC%05d", LBL_KEY(lblfl)); + offset++; + } + + aopPutVal(ic, result, dialectNum(1), 0); + pblaze_emitLabelC(lblfl); + } + } +} + +/*-----------------------------------------------------------------*/ +/* ifxForOp - returns the icode containing the ifx for operand */ +/*-----------------------------------------------------------------*/ +static iCode *ifxForOp(operand * op, iCode * ic) +{ + /* if true symbol then needs to be assigned */ + if (IS_TRUE_SYMOP(op)) + return NULL; + + /* if this has register type condition and + the next instruction is ifx with the same operand + and live to of the operand is upto the ifx only then */ + if (ic->next && ic->next->op == IFX && IC_COND(ic->next)->key == op->key && OP_SYMBOL(op)->liveTo <= ic->next->seq) + return ic->next; + + return NULL; +} + +/*-----------------------------------------------------------------*/ +/* genAndOp - for && operation */ +/*-----------------------------------------------------------------*/ +static void genAndOp(iCode * ic) +{ + operand *left, *right, *result; + symbol *tlbl; + reg_info *r; + + D(pblaze_emitcode(";", "genAnd")); + + left = IC_LEFT(ic); + right = IC_RIGHT(ic); + result = IC_RESULT(ic); + + tlbl = newiTempLabel(NULL); + + /* only for size == 0 */ + aopPutVal(ic, result, dialectNum(0), 0); + + r = toBoolean(ic, left); + pblaze_emitcodeCompare(r->name, dialectNum(0)); + pblaze_emitcode("JUMP", "Z, _LC%05d", LBL_KEY(tlbl)); + + r = toBoolean(ic, right); + pblaze_emitcodeCompare(r->name, dialectNum(0)); + pblaze_emitcode("JUMP", "Z, _LC%05d", LBL_KEY(tlbl)); + + aopPutVal(ic, result, dialectNum(1), 0); + pblaze_emitLabelC(tlbl); + +} + +/*-----------------------------------------------------------------*/ +/* genOrOp - for || operation */ +/*-----------------------------------------------------------------*/ +static void genOrOp(iCode * ic) +{ + operand *left, *right, *result; + symbol *tlbl; + reg_info *r; + + D(pblaze_emitcode(";", "genOrOp")); + + left = IC_LEFT(ic); + right = IC_RIGHT(ic); + result = IC_RESULT(ic); + /* only size == 0 */ + + tlbl = newiTempLabel(NULL); + + pblaze_emitcode("XOR", "%s, %s", aopGetRegName(ic, result, 0), dialectNum(1)); + aopUpdateOpInMem(ic, result, 0); + + r = toBoolean(ic, left); + pblaze_emitcodeCompare(r->name, dialectNum(0)); + pblaze_emitcode("JUMP", "NZ, _LC%05d", LBL_KEY(tlbl)); + r = toBoolean(ic, right); + pblaze_emitcodeCompare(r->name, dialectNum(0)); + pblaze_emitcode("JUMP", "NZ, _LC%05d", LBL_KEY(tlbl)); + + aopPutVal(ic, result, dialectNum(0), 0); + pblaze_emitLabelC(tlbl); +} + +enum { + PBLAZE_AND = 0, PBLAZE_OR, PBLAZE_XOR +}; + +/*-----------------------------------------------------------------*/ +/* genBitWise - generate bitwise operations */ +/*-----------------------------------------------------------------*/ +static void genBitWise(iCode * ic, iCode * ifx, int bitop) +{ + operand *left, *right, *result; + int size, sizeL, sizeR, offset = 0; + + D(pblaze_emitcode(";", "genBitWise")); + + + if ((isOperandLiteral(IC_LEFT(ic)) && !isOperandLiteral(IC_RIGHT(ic))) || + (!isOperandLiteral(IC_RIGHT(ic)) && OP_LIVETO(IC_LEFT(ic)) > ic->seq && OP_LIVETO(IC_RIGHT(ic)) == ic->seq)) { + operand *t = IC_RIGHT(ic); + IC_RIGHT(ic) = IC_LEFT(ic); + IC_LEFT(ic) = t; + } + + left = IC_LEFT(ic); + right = IC_RIGHT(ic); + result = IC_RESULT(ic); + + sizeL = getSize(operandType(left)); + sizeR = getSize(operandType(right)); + size = max(sizeL, sizeR); + + + /* right symbol may ends at this position */ + if (ASSIGN_OPT(result, left) && assignOptTest(ic, IC_RESULT(ic))) { + assignOpt(ic, result, left); + } else { + copyRegisters(ic, result, left, 0, size - 1); + } + + /* right operand is a literal value */ + if (isOperandLiteral(right)) { + unsigned long lit = ulFromVal(OP_VALUE(right)); + + while (size--) { + if (bitop == PBLAZE_AND) { + pblaze_emitcode("AND", "%s, %s", aopGetRegName(ic, result, offset), + dialectNum(valueOffset(lit, offset))); + aopUpdateOpInMem(ic, result, offset); + } + + else if (bitop == PBLAZE_OR) { + pblaze_emitcode("OR", "%s, %s", aopGetRegName(ic, result, offset), + dialectNum(valueOffset(lit, offset))); + aopUpdateOpInMem(ic, result, offset); + } else if (bitop == PBLAZE_XOR) { + pblaze_emitcode("XOR", "%s, %s", aopGetRegName(ic, result, offset), + dialectNum(valueOffset(lit, offset))); + aopUpdateOpInMem(ic, result, offset); + } + offset++; + } + } + + else { + while (size--) { + if (bitop == PBLAZE_AND) { + pblaze_emitcode("AND", "%s, %s", aopGetRegName(ic, result, offset), aopGetRegName(ic, right, offset)); + aopUpdateOpInMem(ic, result, offset); + } else if (bitop == PBLAZE_OR) { + pblaze_emitcode("OR", "%s, %s", aopGetRegName(ic, result, offset), aopGetRegName(ic, right, offset)); + aopUpdateOpInMem(ic, result, offset); + } else if (bitop == PBLAZE_XOR) { + pblaze_emitcode("XOR", "%s, %s", aopGetRegName(ic, result, offset), aopGetRegName(ic, right, offset)); + aopUpdateOpInMem(ic, result, offset); + } + offset++; + } + } +} + +/*-----------------------------------------------------------------*/ +/* genAnd - code for and */ +/*-----------------------------------------------------------------*/ +static void genAnd(iCode * ic, iCode * ifx) +{ + D(pblaze_emitcode(";", "genAND")); + + genBitWise(ic, ifx, PBLAZE_AND); +} + +/*-----------------------------------------------------------------*/ +/* genOr - code for or */ +/*-----------------------------------------------------------------*/ +static void genOr(iCode * ic, iCode * ifx) +{ + D(pblaze_emitcode(";", "genOR")); + + genBitWise(ic, ifx, PBLAZE_OR); +} + +/*-----------------------------------------------------------------*/ +/* genXor - code for xclusive or */ +/*-----------------------------------------------------------------*/ +static void genXor(iCode * ic, iCode * ifx) +{ + D(pblaze_emitcode(";", "genXOR")); + + genBitWise(ic, ifx, PBLAZE_XOR); +} + +/*-----------------------------------------------------------------*/ +/* genInline - write the inline code out */ +/*-----------------------------------------------------------------*/ +static void genInline(iCode * ic) +{ + char *buffer, *bp, *bp1; + bool inComment = FALSE; + + D(pblaze_emitcode(";", "genInline")); + + _G.inLine += (!options.asmpeep); + + buffer = bp = bp1 = Safe_strdup(IC_INLINE(ic)); + + /* emit each line as a code */ + while (*bp) { + switch (*bp) { + case ';': + inComment = TRUE; + ++bp; + break; + + case '\n': + inComment = FALSE; + *bp++ = '\0'; + pblaze_emitcode(bp1, ""); + bp1 = bp; + break; + + default: + if (!inComment && (*bp == ':') && (isspace((unsigned char) bp[1]))) { + ++bp; + *bp = '\0'; + ++bp; + pblaze_emitcode(bp1, ""); + bp1 = bp; + } else + ++bp; + break; + } + } + if (bp1 != bp) + pblaze_emitcode(bp1, ""); + + Safe_free(buffer); + + _G.inLine -= (!options.asmpeep); +} + +/*-----------------------------------------------------------------*/ +/* genRRC - rotate right with carry */ +/*-----------------------------------------------------------------*/ +static void genRRC(iCode * ic) +{ + int offset = 0; + int size; + operand *result, *left; + + D(pblaze_emitcode(";", "genRRC")); + + result = IC_RESULT(ic); + left = IC_LEFT(ic); + size = getSize(operandType(result)); + + /* left and result operands aren't the same */ + if (!pblaze_operandsEqu(IC_RESULT(ic), IC_LEFT(ic))) { + /* assign optimalization (left symbol may ends at this position) */ + if (ASSIGN_OPT(result, left)) { + assignOpt(ic, result, left); + } + /* assign left operand into result operand */ + else { + copyRegisters(ic, result, left, 0, size - 1); + } + } + + if (size == 1) { + pblaze_emitcode("RR", "%s", aopGetRegName(ic, result, 0)); + aopUpdateOpInMem(ic, result, 0); + } else { + pblaze_emitcode("TEST", "%s, %s", aopGetRegName(ic, result, 0), dialectNum(1)); + + while (size--) { + pblaze_emitcode("SRA", "%s", aopGetRegName(ic, result, offset)); + aopUpdateOpInMem(ic, result, offset); + offset++; + } + + } +} + +/*-----------------------------------------------------------------*/ +/* genRLC - generate code for rotate left with carry */ +/*-----------------------------------------------------------------*/ +static void genRLC(iCode * ic) +{ + int offset = 0; + int size; + operand *result, *left; + + D(pblaze_emitcode(";", "genRLC")); + + result = IC_RESULT(ic); + left = IC_LEFT(ic); + size = getSize(operandType(result)); + + /* left and result operands aren't the same */ + if (!pblaze_operandsEqu(IC_RESULT(ic), IC_LEFT(ic))) { + /* assign optimalization (left symbol may ends at this position) */ + if (ASSIGN_OPT(result, left)) { + assignOpt(ic, result, left); + } + /* assign left operand into result operand */ + else { + copyRegisters(ic, result, left, 0, size - 1); + } + } + + if (size == 1) { + pblaze_emitcode("RL", "%s", aopGetRegName(ic, result, 0)); + aopUpdateOpInMem(ic, result, 0); + } else { + pblaze_emitcode("TEST", "%s, %s", aopGetRegName(ic, result, size - 1), dialectNum(128)); + + while (size--) { + pblaze_emitcode("SLA", "%s", aopGetRegName(ic, result, offset)); + aopUpdateOpInMem(ic, result, offset); + offset++; + } + + } +} + +/*-----------------------------------------------------------------*/ +/* genGetHbit - generates code get highest order bit */ +/*-----------------------------------------------------------------*/ +static void genGetHbit(iCode * ic) +{ + int offset = 0; + int size, sizeL; + operand *result, *left; + + D(pblaze_emitcode(";", "genGetHBit")); + + result = IC_RESULT(ic); + left = IC_LEFT(ic); + size = getSize(operandType(result)); + sizeL = getSize(operandType(left)); + + while (size--) { + pblaze_emitcode("XOR", "%s, %s", aopGetRegName(ic, result, offset), aopGetRegName(ic, result, offset)); + aopUpdateOpInMem(ic, result, offset); + + if (size == 0) { + pblaze_emitcode("TEST", "%s, %s", aopGetRegName(ic, left, sizeL - 1), dialectNum(128)); + pblaze_emitcodeADDCY(aopGetRegName(ic, result, 0), dialectNum(0)); + aopUpdateOpInMem(ic, result, 0); + } + + offset++; + } +} + +/*-----------------------------------------------------------------*/ +/* leftMaskNumber - generates bit mask for AND operation */ +/*-----------------------------------------------------------------*/ +int leftMaskNumber(int ones) +{ + int num = 0; + if (ones >= 1) + num += 128; + if (ones >= 2) + num += 64; + if (ones >= 3) + num += 32; + if (ones >= 4) + num += 16; + if (ones >= 5) + num += 8; + if (ones >= 6) + num += 4; + if (ones >= 7) + num += 2; + if (ones >= 8) + num += 1; + return num; +} + +/*-----------------------------------------------------------------*/ +/* rightMaskNumber - generates bit mask for AND operation */ +/*-----------------------------------------------------------------*/ +int rightMaskNumber(int ones) +{ + int num = 0; + if (ones >= 1) + num += 1; + if (ones >= 2) + num += 2; + if (ones >= 3) + num += 4; + if (ones >= 4) + num += 8; + if (ones >= 5) + num += 16; + if (ones >= 6) + num += 32; + if (ones >= 7) + num += 64; + if (ones >= 8) + num += 128; + return num; +} + +/*-----------------------------------------------------------------*/ +/* genShiftLeftLit - shift left by a known amount */ +/*-----------------------------------------------------------------*/ +static void genShiftLeftLit(iCode * ic) +{ + operand *left, *right, *result; + int i, size, shCount, lByteZ, offset = 0; + + D(pblaze_emitcode(";", "genShiftLeftLit")); + + result = IC_RESULT(ic); + right = IC_RIGHT(ic); + left = IC_LEFT(ic); + size = getSize(operandType(result)); + + shCount = (int) ulFromVal(OP_VALUE(right)); + + /* shift count = 0 */ + if (shCount == 0) { + if (ASSIGN_OPT(result, left)) { + assignOpt(ic, result, left); + } else { + copyRegisters(ic, result, left, 0, size - 1); + } + return; + } + + /* shift count > size */ + if (shCount >= (size * 8)) { + while (size--) + aopPutVal(ic, result, dialectNum(0), offset++); + return; + } + offset = 0; + + switch (size) { + case 1: + + if (ASSIGN_OPT(result, left)) { + assignOpt(ic, result, left); + } + /* assign left operand into result operand */ + else { + copyRegisters(ic, result, left, 0, 0); + } + + if (shCount <= 4) { + while (shCount--) { + pblaze_emitcode("SL0", "%s", aopGetRegName(ic, result, 0)); + aopUpdateOpInMem(ic, result, 0); + } + } + // shift left more than 4 times can be converted to RR & AND (less instructions requied) + else { + i = shCount = 8 - shCount; + while (shCount--) { + pblaze_emitcode("RR", "%s", aopGetRegName(ic, result, 0)); + aopUpdateOpInMem(ic, result, 0); + } + pblaze_emitcode("AND", "%s, %s", aopGetRegName(ic, result, 0), dialectNum(leftMaskNumber(i))); + aopUpdateOpInMem(ic, result, 0); + } + break; + + case 2: + + if (shCount >= 8) { + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 0), dialectNum(0)); + aopUpdateOpInMem(ic, result, 0); + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 1), aopGetRegName(ic, left, 0)); + aopUpdateOpInMem(ic, result, 1); + + shCount -= 8; + + while (shCount--) { + pblaze_emitcode("SL0", "%s", aopGetRegName(ic, result, 1)); + aopUpdateOpInMem(ic, result, 1); + } + } else { + if (ASSIGN_OPT(result, left)) { + assignOpt(ic, result, left); + } else { + copyRegisters(ic, result, left, 0, size - 1); + } + + while (shCount--) { + pblaze_emitcode("SL0", "%s", aopGetRegName(ic, result, 0)); + aopUpdateOpInMem(ic, result, 0); + pblaze_emitcode("SLA", "%s", aopGetRegName(ic, result, 1)); + aopUpdateOpInMem(ic, result, 1); + } + } + break; + + case 3: + assert("unknown type\n"); + break; + + case 4: + lByteZ = 0; + if (shCount >= 24) { + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 0), dialectNum(0)); + aopUpdateOpInMem(ic, result, 0); + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 1), dialectNum(0)); + aopUpdateOpInMem(ic, result, 1); + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 2), dialectNum(0)); + aopUpdateOpInMem(ic, result, 2); + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 3), aopGetRegName(ic, left, 0)); + aopUpdateOpInMem(ic, result, 3); + lByteZ = 3; + shCount -= 24; + } + if (shCount >= 16) { + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 0), dialectNum(0)); + aopUpdateOpInMem(ic, result, 0); + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 1), dialectNum(0)); + aopUpdateOpInMem(ic, result, 1); + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 2), aopGetRegName(ic, left, 0)); + aopUpdateOpInMem(ic, result, 2); + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 3), aopGetRegName(ic, left, 1)); + aopUpdateOpInMem(ic, result, 3); + lByteZ = 2; + shCount -= 16; + } + + if (shCount >= 8) { + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 0), dialectNum(0)); + aopUpdateOpInMem(ic, result, 0); + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 1), aopGetRegName(ic, left, 0)); + aopUpdateOpInMem(ic, result, 1); + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 2), aopGetRegName(ic, left, 1)); + aopUpdateOpInMem(ic, result, 2); + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 3), aopGetRegName(ic, left, 2)); + aopUpdateOpInMem(ic, result, 3); + lByteZ = 1; + shCount -= 8; + } + + if (lByteZ == 0) { + if (ASSIGN_OPT(result, left)) { + assignOpt(ic, result, left); + } else { + copyRegisters(ic, result, left, 0, size - 1); + } + } + if (shCount) { + switch (lByteZ) { + case 0: + while (shCount--) { + pblaze_emitcode("SL0", "%s", aopGetRegName(ic, result, 0)); + aopUpdateOpInMem(ic, result, 0); + pblaze_emitcode("SLA", "%s", aopGetRegName(ic, result, 1)); + aopUpdateOpInMem(ic, result, 1); + pblaze_emitcode("SLA", "%s", aopGetRegName(ic, result, 2)); + aopUpdateOpInMem(ic, result, 2); + pblaze_emitcode("SLA", "%s", aopGetRegName(ic, result, 3)); + aopUpdateOpInMem(ic, result, 3); + } + break; + + case 1: + while (shCount--) { + pblaze_emitcode("SL0", "%s", aopGetRegName(ic, result, 1)); + aopUpdateOpInMem(ic, result, 1); + pblaze_emitcode("SLA", "%s", aopGetRegName(ic, result, 2)); + aopUpdateOpInMem(ic, result, 2); + pblaze_emitcode("SLA", "%s", aopGetRegName(ic, result, 3)); + aopUpdateOpInMem(ic, result, 3); + } + break; + + case 2: + while (shCount--) { + pblaze_emitcode("SL0", "%s", aopGetRegName(ic, result, 2)); + aopUpdateOpInMem(ic, result, 2); + pblaze_emitcode("SLA", "%s", aopGetRegName(ic, result, 3)); + aopUpdateOpInMem(ic, result, 3); + } + break; + + case 3: + while (shCount--) { + pblaze_emitcode("SL0", "%s", aopGetRegName(ic, result, 3)); + aopUpdateOpInMem(ic, result, 3); + } + break; + } + } + break; + } +} + +/*-----------------------------------------------------------------*/ +/* genLeftShift - generates code for left shifting */ +/*-----------------------------------------------------------------*/ +static void genLeftShift(iCode * ic) +{ + operand *left, *right, *result; + int size, offset = 0; + symbol *slbl, *elbl; + reg_info *reg; + int notTemp; + + D(pblaze_emitcode(";", "genShiftLeft")); + + if (isOperandLiteral(IC_RIGHT(ic))) { + genShiftLeftLit(ic); + return; + } + + result = IC_RESULT(ic); + right = IC_RIGHT(ic); + left = IC_LEFT(ic); + size = getSize(operandType(result)); + + + /* left and result operands aren't the same */ + if (!pblaze_operandsEqu(result, left)) { + /* assign optimalization (left symbol may ends at this position) */ + if (ASSIGN_OPT(result, left)) { + assignOpt(ic, result, left); + } + /* assign left operand into result operand */ + else { + copyRegisters(ic, result, left, 0, size - 1); + } + } + + /* shift count is unknown then we have to form a loop + Note: we take only the lower order byte since shifting + more that 32 bits make no sense anyway, */ + + if (ic->seq >= OP_SYMBOL(right)->liveTo) { + reg = aopGetReg(ic, right, 0); + notTemp = 1; + } else { + reg = getReg(ic); + lockReg(reg); + pblaze_emitcode("LOAD", "%s, %s", reg->name, aopGetRegName(ic, right, 0)); + notTemp = 0; + } + + + elbl = newiTempLabel(NULL); + slbl = newiTempLabel(NULL); + + pblaze_emitLabelC(slbl); + + pblaze_emitcodeCompare(reg->name, dialectNum(0)); + pblaze_emitcode("JUMP", "Z, _LC%05d", LBL_KEY(elbl)); + + pblaze_emitcode("SUB", "%s, %s", reg->name, dialectNum(1)); + if (notTemp) + aopUpdateOpInMem(ic, right, 0); + // zero carry flag + pblaze_emitcode("AND", "sB, sB"); + + while (size--) { + pblaze_emitcode("SLA", "%s", aopGetRegName(ic, result, offset++)); + aopUpdateOpInMem(ic, result, offset); + } + + pblaze_emitcode("JUMP", "_LC%05d", LBL_KEY(slbl)); + + pblaze_emitLabelC(elbl); + + unlockReg(reg); +} + +/*-----------------------------------------------------------------*/ +/* genShiftRightLit - generate for right shift with known count */ +/*-----------------------------------------------------------------*/ +static void genShiftRightLit(iCode * ic) +{ + operand *left, *right, *result; + int i, size, shCount, hByteZ, offset = 0; + + D(pblaze_emitcode(";", "genShiftRightLit")); + + result = IC_RESULT(ic); + right = IC_RIGHT(ic); + left = IC_LEFT(ic); + size = getSize(operandType(result)); + + shCount = (int) ulFromVal(OP_VALUE(right)); + if (shCount == 0) { + if (ASSIGN_OPT(result, left)) { + assignOpt(ic, result, left); + } else { + copyRegisters(ic, result, left, 0, size - 1); + } + return; + } + + if (shCount >= (size * 8)) { + while (size--) { + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, offset), dialectNum(0)); + aopUpdateOpInMem(ic, result, offset); + offset++; + } + return; + } + offset = 0; + switch (size) { + case 1: + + if (ASSIGN_OPT(result, left)) { + assignOpt(ic, result, left); + } + /* assign left operand into result operand */ + else { + copyRegisters(ic, result, left, 0, 0); + } + + if (shCount <= 4) { + while (shCount--) { + pblaze_emitcode("SR0", "%s", aopGetRegName(ic, result, 0)); + aopUpdateOpInMem(ic, result, 0); + } + } + // shift right more than 4 times can be converted to RL & AND (less instructions requied) + else { + i = shCount = 8 - shCount; + while (shCount--) { + pblaze_emitcode("RL", "%s", aopGetRegName(ic, result, 0)); + aopUpdateOpInMem(ic, result, 0); + } + pblaze_emitcode("AND", "%s, %s", aopGetRegName(ic, result, 0), dialectNum(rightMaskNumber(i))); + aopUpdateOpInMem(ic, result, 0); + } + break; + + case 2: + + if (shCount >= 8) { + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 0), aopGetRegName(ic, left, 1)); + aopUpdateOpInMem(ic, result, 0); + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 1), dialectNum(1)); + aopUpdateOpInMem(ic, result, 1); + + shCount -= 8; + + while (shCount--) { + pblaze_emitcode("SR0", "%s", aopGetRegName(ic, result, 0)); + aopUpdateOpInMem(ic, result, 0); + } + } else { + if (ASSIGN_OPT(result, left)) { + assignOpt(ic, result, left); + } else { + copyRegisters(ic, result, left, 0, size - 1); + } + + while (shCount--) { + pblaze_emitcode("SR0", "%s", aopGetRegName(ic, result, 1)); + aopUpdateOpInMem(ic, result, 1); + pblaze_emitcode("SRA", "%s", aopGetRegName(ic, result, 0)); + aopUpdateOpInMem(ic, result, 0); + } + } + break; + + case 3: + assert("unknown type\n"); + break; + + case 4: + hByteZ = 0; + if (shCount >= 24) { + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 0), aopGetRegName(ic, left, 3)); + aopUpdateOpInMem(ic, result, 0); + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 1), dialectNum(0)); + aopUpdateOpInMem(ic, result, 1); + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 2), dialectNum(0)); + aopUpdateOpInMem(ic, result, 2); + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 3), dialectNum(0)); + aopUpdateOpInMem(ic, result, 3); + + hByteZ = 3; + shCount -= 24; + } + if (shCount >= 16) { + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 0), aopGetRegName(ic, left, 2)); + aopUpdateOpInMem(ic, result, 0); + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 1), aopGetRegName(ic, left, 3)); + aopUpdateOpInMem(ic, result, 1); + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 2), dialectNum(0)); + aopUpdateOpInMem(ic, result, 2); + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 3), dialectNum(0)); + aopUpdateOpInMem(ic, result, 3); + + hByteZ = 2; + shCount -= 16; + } + + if (shCount >= 8) { + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 0), aopGetRegName(ic, left, 1)); + aopUpdateOpInMem(ic, result, 0); + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 1), aopGetRegName(ic, left, 2)); + aopUpdateOpInMem(ic, result, 1); + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 2), aopGetRegName(ic, left, 3)); + aopUpdateOpInMem(ic, result, 2); + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, 3), dialectNum(0)); + aopUpdateOpInMem(ic, result, 3); + + hByteZ = 1; + shCount -= 8; + } + + if (hByteZ == 0) { + if (ASSIGN_OPT(result, left)) { + assignOpt(ic, result, left); + } else { + copyRegisters(ic, result, left, 0, size - 1); + } + } + if (shCount) { + switch (hByteZ) { + case 0: + while (shCount--) { + pblaze_emitcode("SR0", "%s", aopGetRegName(ic, result, 3)); + aopUpdateOpInMem(ic, result, 3); + pblaze_emitcode("SRA", "%s", aopGetRegName(ic, result, 2)); + aopUpdateOpInMem(ic, result, 2); + pblaze_emitcode("SRA", "%s", aopGetRegName(ic, result, 1)); + aopUpdateOpInMem(ic, result, 1); + pblaze_emitcode("SRA", "%s", aopGetRegName(ic, result, 0)); + aopUpdateOpInMem(ic, result, 0); + } + break; + + case 1: + while (shCount--) { + pblaze_emitcode("SR0", "%s", aopGetRegName(ic, result, 2)); + aopUpdateOpInMem(ic, result, 2); + pblaze_emitcode("SRA", "%s", aopGetRegName(ic, result, 1)); + aopUpdateOpInMem(ic, result, 1); + pblaze_emitcode("SRA", "%s", aopGetRegName(ic, result, 0)); + aopUpdateOpInMem(ic, result, 0); + } + break; + + case 2: + while (shCount--) { + pblaze_emitcode("SR0", "%s", aopGetRegName(ic, result, 1)); + aopUpdateOpInMem(ic, result, 1); + pblaze_emitcode("SRA", "%s", aopGetRegName(ic, result, 0)); + aopUpdateOpInMem(ic, result, 0); + } + break; + + case 3: + while (shCount--) { + pblaze_emitcode("SR0", "%s", aopGetRegName(ic, result, 0)); + aopUpdateOpInMem(ic, result, 0); + } + break; + } + } + break; + } + +} + +/*-----------------------------------------------------------------*/ +/* genRightShift - generate code for right shifting */ +/*-----------------------------------------------------------------*/ +static void genRightShift(iCode * ic) +{ + operand *left, *right, *result; + int size; + symbol *slbl, *elbl; + reg_info *reg; + int notTemp; + + D(pblaze_emitcode(";", "genShiftRight")); + + if (isOperandLiteral(IC_RIGHT(ic))) { + genShiftRightLit(ic); + return; + } + + result = IC_RESULT(ic); + right = IC_RIGHT(ic); + left = IC_LEFT(ic); + size = getSize(operandType(result)); + + + /* left and result operands aren't the same */ + if (!pblaze_operandsEqu(result, left)) { + /* assign optimalization (left symbol may ends at this position) */ + if (ASSIGN_OPT(result, left)) { + assignOpt(ic, result, left); + } + /* assign left operand into result operand */ + else { + copyRegisters(ic, result, left, 0, size - 1); + } + } + + /* shift count is unknown then we have to form a loop + Note: we take only the lower order byte since shifting + more that 32 bits make no sense anyway, */ + + if (ic->seq >= OP_SYMBOL(right)->liveTo) { + reg = aopGetReg(ic, right, 0); + notTemp = 1; + } else { + reg = getReg(ic); + lockReg(reg); + pblaze_emitcode("LOAD", "%s, %s", reg->name, aopGetRegName(ic, right, 0)); + notTemp = 0; + } + + + elbl = newiTempLabel(NULL); + slbl = newiTempLabel(NULL); + + pblaze_emitLabelC(slbl); + + pblaze_emitcodeCompare(reg->name, dialectNum(0)); + pblaze_emitcode("JUMP", "Z, _LC%05d", LBL_KEY(elbl)); + + pblaze_emitcode("SUB", "%s, %s", reg->name, dialectNum(1)); + if (notTemp) + aopUpdateOpInMem(ic, right, 0); + + // zero carry flag + pblaze_emitcode("AND", "sB, sB"); + + while (size--) { + pblaze_emitcode("SRA", "%s", aopGetRegName(ic, result, size)); + aopUpdateOpInMem(ic, result, size); + } + + pblaze_emitcode("JUMP", "_LC%05d", LBL_KEY(slbl)); + + pblaze_emitLabelC(elbl); + + unlockReg(reg); +} + +/*-----------------------------------------------------------------*/ +/* genIfx - generate code for Ifx statement */ +/*-----------------------------------------------------------------*/ +static void genIfx(iCode * ic, iCode * popIc) +{ + operand *cond = IC_COND(ic); + symbol *lbl; + reg_info *reg; + + D(pblaze_emitcode(";", "genIFX")); + + lbl = newiTempLabel(NULL); + + reg = toBoolean(ic, cond); + pblaze_emitcodeCompare(reg->name, dialectNum(0)); + + if (IC_TRUE(ic)) { + pblaze_emitcode("JUMP", "Z, _LC%05d", LBL_KEY(lbl)); + pblaze_emitcode("JUMP", "_L%05d", LBL_KEY(IC_TRUE(ic))); + pblaze_emitLabelC(lbl); + } + + else { + pblaze_emitcode("JUMP", "NZ, _LC%05d", LBL_KEY(lbl)); + pblaze_emitcode("JUMP", "_L%05d", LBL_KEY(IC_FALSE(ic))); + pblaze_emitLabelC(lbl); + } + +} + +/*-----------------------------------------------------------------*/ +/* genAddrOf - generates code for address of */ +/*-----------------------------------------------------------------*/ +static void genAddrOf(iCode * ic) +{ + D(pblaze_emitcode(";", "genAddrOf")); + + operand *result, *left; + int size, inR; + memMap *mAddr; + + result = IC_RESULT(ic); + left = IC_LEFT(ic); + + if (isInOutRef(left)) { + addInOutRef(result, NULL); + return; + } + + size = getSize(operandType(result)); + + mAddr = isOpInMem(left); + inR = isOpInReg(left); + + if (!mAddr && inR) { + moveOpToMem(left); + mAddr = isOpInMem(left); + } + else if (!mAddr) { + mAddr = firstFreeMem(); + } + if (!mAddr) { + fprintf(stderr, "%s:%d: pblaze port error: operand not in the memory\n", __FILE__, __LINE__); + exit(1); + } + if (!operName(mAddr->addr)) + aopPutVal(ic, result, dialectNum(mAddr->addr), 0); + else + aopPutVal(ic, result, operName(mAddr->addr), 0); + + _G.ptrOff = 0; +} + +/*-----------------------------------------------------------------*/ +/* genValueAtAddr - generates code for value at addres */ +/*-----------------------------------------------------------------*/ +static void genValueAtAddr(iCode * ic) +{ + D(pblaze_emitcode(";", "genValueAtAddr")); + + int size, i; + unsigned long lit = 0L; + operand *result, *left; + + result = IC_RESULT(ic); + left = IC_LEFT(ic); + size = getSize(operandType(result)); + + /* address given as a literal value */ + if (isOperandLiteral(left)) { + + lit = ulFromVal(OP_VALUE(left)); + + for (i = size - 1; i >= 0; i--) { + pblaze_emitcodeFetch(aopGetRegName(ic, result, i), dialectNum(valueOffset(lit, 0))); + lit++; + } + + } else { + + if (size == 1) { + /* left operand is an INPUT reference */ + if (isInOutRef(left)) { + pblaze_emitcodeInput(ic, result, 0, left); + } else { + pblaze_emitcodeFetch(aopGetRegName(ic, result, 0), aopGetRegName(ic, left, 0)); + } + aopUpdateOpInMem(ic, result, 0); + } else if (size > 1) { + /* left operand is an INPUT reference */ + if (isInOutRef(left)) { + pblaze_emitcodeInput(ic, result, 0, left); + aopUpdateOpInMem(ic, result, 0); + for (i = 1; i < size; i++) { + aopPutVal(ic, result, dialectNum(0), i); + aopUpdateOpInMem(ic, result, i); + } + + } else { + + for (i = size - 1; i >= 0; i--) { + pblaze_emitcodeFetch(aopGetRegName(ic, result, i), aopGetRegName(ic, left, 0)); + aopUpdateOpInMem(ic, result, i); + + if (i != 0) { + pblaze_emitcode("ADD", "%s, %s", aopGetRegName(ic, left, 0), dialectNum(1)); + aopUpdateOpInMem(ic, left, 0); + } + } + + /* pointer will be used later, return to the begining */ + if (OP_LIVETO(left) > ic->seq) { + pblaze_emitcode("SUB", "%s, %s", aopGetRegName(ic, left, 0), dialectNum(size - 1)); + aopUpdateOpInMem(ic, left, 0); + } + } + } + } +} + +/*-----------------------------------------------------------------*/ +/* genAssign - generate code for assignment */ +/*-----------------------------------------------------------------*/ +static void genAssign(iCode * ic) +{ + operand *result, *right; + int size, offset; + int i; + memMap *mem; + + D(pblaze_emitcode(";", "genAssign")); + + result = IC_RESULT(ic); + right = IC_RIGHT(ic); + + /* if they are the same */ + if (pblaze_operandsEqu(result, right)) + return; + + size = getSize(operandType(result)); + + /* assign from memory */ + if (IS_OP_GLOBALVOLATILE(right) || right->isaddr) { + + if(isInOutRef(result)) { + pblaze_emitcodeOutput(ic, aopGetRegName(ic, right, 0), result); + } else { + for (i = 0; i < size; i++) { + aopMoveReg(ic, result, aopGetReg(ic, right, i), i); + } + } + } + + /* right side is a literal value */ + else if (isOperandLiteral(right)) { + /* assign literal values into registers */ + assignLiteral(result, right, ic); + } + + /* should be on the stack */ + else if (IS_OP_PARM(right) && strlen(OP_SYMBOL(right)->rname) == 0) { + size = getSize(operandType(right)); + offset = size - 1; + + while (size--) { + popStack(aopGetReg(ic, result, offset)->rIdx, 1); + offset--; + } + } + + /* right side is a symbol */ + else if (OP_SYMBOL(right)) { + size = getSize(operandType(right)); + + /* result is a pointer into memory */ + if (POINTER_SET(ic)) { + + for (i = size - 1; i >= 0; i--) { + aopPutReg(ic, result, aopGetReg(ic, right, i), i); + if (i > 0) { + pblaze_emitcode("ADD", "%s, %s", aopGetRegName(ic, result, 0), dialectNum(1)); + aopUpdateOpInMem(ic, result, 0); + } + } + /* pointer will be used later, return to the begining */ + if (size > 1 && OP_LIVETO(result) > ic->seq) { + pblaze_emitcode("SUB", "%s, %s", aopGetRegName(ic, result, 0), dialectNum(size - 1)); + aopUpdateOpInMem(ic, result, 0); + } + + } + + /* assign optimalization (right symbol may ends at this position) */ + else if (ASSIGN_OPT(result, right) && assignOptTest(ic, IC_RESULT(ic))) { + assignOpt(ic, result, right); + } + + /* assign registers */ + else if (size == getSize(operandType(result))) { + /* copy values from the right operand into the result operand */ + copyRegisters(ic, result, right, 0, size - 1); + } + // + else { + fprintf(stderr, "pblaze port error: genAssign unknown error\n"); + exit(1); + } + } + + if (IS_OP_GLOBAL(result) && !isOpVolatile(result)) { + + /* probably global value assigment */ + if (GLOB_ASSIGN) { + size = getSize(operandType(result)); + + for (i = size - 1; i >= 0; i--) { + if (OP_SYMBOL(result)->regs[i] && (mem = isOffsetInMem(result, i)) != NULL) + pblaze_emitcodeStore(OP_SYMBOL(result)->regs[i]->name, operName(mem->addr)); + } + } else { + globalChanged(result, IN_REG); + } + } +} + +/*-----------------------------------------------------------------*/ +/* genJumpTab - genrates code for jump table */ +/*-----------------------------------------------------------------*/ +static void genJumpTab(iCode * ic) +{ + // D (pblaze_emitcode (";", "genJumpTab")); + /* not easy to implement without access to the Instruction pointer */ + assert(0); +} + +/*-----------------------------------------------------------------*/ +/* genCast - gen code for casting */ +/*-----------------------------------------------------------------*/ +static void genCast(iCode * ic) +{ + D(pblaze_emitcode(";", "genCast")); + + operand *result = IC_RESULT(ic); + + sym_link *rtype = operandType(IC_RIGHT(ic)); + operand *right = IC_RIGHT(ic); + int sizeRes, sizeRight, i, opt = 0; + + sizeRes = getSize(operandType(result)); + sizeRight = getSize(operandType(right)); + + /* if they are equivalent then do nothing */ + if (pblaze_operandsEqu(IC_RESULT(ic), IC_RIGHT(ic))) + return; + + //literal and bool + if (isOperandLiteral(right)) { + + } + + else if (IS_PTR(rtype)) { + if (OP_LIVETO(right) > ic->seq) + copyRegisters(ic, result, right, 0, 0); + else + assignOpt(ic, result, right); + } + + /* if they are the same size or less */ + else if (sizeRes <= sizeRight) { + + /* right symbol may ends at this position */ + if (ASSIGN_OPT(result, right) && assignOptTest(ic, IC_RESULT(ic))) { + assignOpt(ic, result, right); + } else { + /* assign the casted value */ + copyRegisters(ic, result, right, 0, sizeRes - 1); + } + } + + /* the size of destination is greater than the size of the source */ + else { + + /* right symbol may ends at this position */ + if (ASSIGN_OPT(result, right) && assignOptTest(ic, IC_RESULT(ic))) { + assignOpt(ic, result, right); + opt = 1; + } else { + + copyRegisters(ic, result, right, 0, sizeRight - 1); + } + + /* we need to extend the sign */ + if (opt) + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, sizeRight), dialectNum(0)); + aopUpdateOpInMem(ic, result, sizeRight); + pblaze_emitcode("TEST", "%s, %s", aopGetRegName(ic, result, sizeRight - 1), dialectNum(128)); + pblaze_emitcodeSUBCY(aopGetRegName(ic, result, sizeRight), dialectNum(0)); + aopUpdateOpInMem(ic, result, sizeRight); + + for (i = sizeRight + 1; i < sizeRes; i++) { + pblaze_emitcode("LOAD", "%s, %s", aopGetRegName(ic, result, i), aopGetRegName(ic, result, sizeRight)); + aopUpdateOpInMem(ic, result, i); + } + } + +} + +/*-----------------------------------------------------------------*/ +/* genReceive - generate code for a receive iCode */ +/*-----------------------------------------------------------------*/ +static void genReceive(iCode * ic) +{ + operand *result, *left; + symbol *name; + reg_info *r; + value *val; + char *valName; + int size, params; + int i; + int rMax = SEND_REG_COUNT; + int rfrst = SEND_REG_FIRST; + + D(pblaze_emitcode(";", "genReceive")); + + result = IC_RESULT(ic); + left = IC_LEFT(ic); + size = getSize(operandType(result)); + params = 0; + + /* test parameter */ + if (result && left) { + + name = OP_SYMBOL(left); + val = FUNC_ARGS(name->type); + + if (SPIL_LOC(result)) + valName = SPIL_LOC(result)->rname; + else + valName = OP_SYMBOL(result)->rname; + /* find parameter position */ + while (val) { + sprintf(buffer, "%s%s_", name->rname, val->name); + if (strstr(valName, buffer)) + break; + + params += getSize(val->type); + val = val->next; + } + + recvCnt = params; + } + + /* symbol is in the registers */ + if (recvCnt <= rMax && (rMax - recvCnt) >= size) { + for (i = 0; i < size; i++) { + aopPutReg(ic, result, pblaze_regWithIdx(rfrst + recvCnt), i); + recvCnt++; + } + } + /* not enough registers -> is in the stack */ + else { + if (OP_LIVETO(result) > ic->seq) { + for (i = size - 1; i >= 0; i--) { + if (isOpVolatile(result)) { + r = getReg(ic); + lockReg(r); + popStack(r->rIdx, 0); + aopPutReg(ic, result, r, i); + unlockReg(r); + } else { + aopGetReg(ic, result, i); + popStack(OP_SYMBOL(result)->regs[i]->rIdx, 0); + aopUpdateOpInMem(ic, result, i); + } + } + } else { + pblaze_emitcode("ADD", "sF, %s", dialectNum(size)); + } + } + +} + + + +/*-----------------------------------------------------------------*/ +/* genDummyRead - generate code for dummy read of volatiles */ +/*-----------------------------------------------------------------*/ +static void genDummyRead(iCode * ic) +{ + pblaze_emitcode("; genDummyRead", ""); + pblaze_emitcode("; not implemented", ""); + + ic = ic; +} + +/*-----------------------------------------------------------------*/ +/* genPBLAZECode - generate code for XILINX PicoBlaze controllers */ +/*-----------------------------------------------------------------*/ +void genPBLAZECode(iCode * lic) +{ + iCode *ic; + int cln = 0; + lineHead = lineCurr = NULL; + deleteSet(&_G.inOutSet); + + if (!initGen) { + _G.rUsedVect = newBitVect(pblaze_nRegs); + clearBitVect(_G.rUsedVect); + _G.isCalleSaves = 0; + _G.onStack = 0; + _GFunc.mschar = 0; + _GFunc.muschar = 0; + _GFunc.mint = 0; + _GFunc.mlong = 0; + _GFunc.dschar = 0; + _GFunc.duschar = 0; + _GFunc.modschar = 0; + _GFunc.moduschar = 0; + _GFunc.dsint = 0; + _GFunc.dusint = 0; + _GFunc.modsint = 0; + _GFunc.modusint = 0; + _GFunc.dslong = 0; + _GFunc.duslong = 0; + _GFunc.modslong = 0; + _GFunc.moduslong = 0; + initGen = 1; + } + + recvCnt = 0; + + /* print the allocation information */ + //if (allocInfo && currFunc) + // printAllocInfo (currFunc, codeOutBuf); + + /* if debug information required */ + if (options.debug && currFunc) { + debugFile->writeFunction(currFunc, lic); + } + + for (ic = lic; ic; ic = ic->next) { + if (ic->generated) + continue; + + _G.current_iCode = ic; + + if (ic->lineno && cln != ic->lineno) { + if (options.debug) { + debugFile->writeCLine(ic); + } + if (!options.noCcodeInAsm) { + pblaze_emitcode(";", "%s:%d: %s", ic->filename, ic->lineno, printCLine(ic->filename, ic->lineno)); + } + cln = ic->lineno; + } + + if (!(ic->op == CALL || ic->op == SEND)) { + clearUnusedOpFromReg(ic); + clearUnusedOpFromMem(ic); + + } + + /* depending on the operation */ + switch (ic->op) { + case '!': + genNot(ic); + break; + + case '~': + genCpl(ic); + break; + + case UNARYMINUS: + genUminus(ic); + break; + + case IPUSH: + genIpush(ic); + break; + + case IPOP: + genIpop(ic); + break; + + case CALL: + genCall(ic); + break; + + case PCALL: + genPcall(ic); + break; + + case FUNCTION: + genFunction(ic); + break; + + case ENDFUNCTION: + genEndFunction(ic); + break; + + case RETURN: + genRet(ic); + break; + + case LABEL: + genLabel(ic); + break; + + case GOTO: + genGoto(ic); + break; + + case '+': + genPlus(ic); + break; + + case '-': + genMinus(ic); + break; + + case '*': + genMult(ic); + break; + + case '/': + genDiv(ic); + break; + + case '%': + genMod(ic); + break; + + case '>': + genCmpGt(ic, ifxForOp(IC_RESULT(ic), ic)); + break; + + case '<': + genCmpLt(ic, ifxForOp(IC_RESULT(ic), ic)); + break; + + case LE_OP: + case GE_OP: + case NE_OP: + /* note these two are xlated by algebraic equivalence + in decorateType() in SDCCast.c */ + werror(E_INTERNAL_ERROR, __FILE__, __LINE__, "got '>=' or '<=' shouldn't have come here"); + break; + + case EQ_OP: + genCmpEq(ic, ifxForOp(IC_RESULT(ic), ic)); + break; + + case AND_OP: + genAndOp(ic); + break; + + case OR_OP: + genOrOp(ic); + break; + + case '^': + genXor(ic, ifxForOp(IC_RESULT(ic), ic)); + break; + + case '|': + genOr(ic, ifxForOp(IC_RESULT(ic), ic)); + break; + + case BITWISEAND: + genAnd(ic, ifxForOp(IC_RESULT(ic), ic)); + break; + + case INLINEASM: + genInline(ic); + break; + + case RRC: + genRRC(ic); + break; + + case RLC: + genRLC(ic); + break; + + case GETHBIT: + genGetHbit(ic); + break; + + case LEFT_OP: + genLeftShift(ic); + break; + + case RIGHT_OP: + genRightShift(ic); + break; + + case '=': + genAssign(ic); + break; + + case IFX: + genIfx(ic, NULL); + break; + + case ADDRESS_OF: + genAddrOf(ic); + break; + + case GET_VALUE_AT_ADDRESS: + genValueAtAddr(ic); + break; + + case JUMPTABLE: + genJumpTab(ic); + break; + + case CAST: + genCast(ic); + break; + + case RECEIVE: + genReceive(ic); + break; + + case SEND: + addSet(&_G.sendSet, ic); + break; + + case DUMMY_READ_VOLATILE: + genDummyRead(ic); + break; + + default: + ic = ic; + printf("nogen: %d\n", ic->op); + } + } + + //now we are ready to call the peep hole optimizer + if (!options.nopeep) + peepHole(&lineHead); + + + /* now do the actual printing */ + printLine(lineHead, codeOutBuf); + return; +} diff -NaurbB sdcc-src-3.1.0/src/pblaze/gen.h sdcc-src-3.1.0-pblaze/src/pblaze/gen.h --- sdcc-src-3.1.0/src/pblaze/gen.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/pblaze/gen.h 2011-12-05 23:50:29.120184900 +0100 @@ -0,0 +1,139 @@ +/*------------------------------------------------------------------------- +gen.h - header file for code generation for XILINX PICOBLAZE + +Author: + Jakub Hornik, xhorni00<at>stud.fit.vutbr.cz +Master Thesis Project: + Compiler Back-End of Subset of Language C for 8-Bit Processor +Date: + 2011 + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ + +#ifndef SDCCGENPBLAZE_H +#define SDCCGENPBLAZE_H + +#include "main.h" + +#define GLOB_ASSIGN (ic->next == NULL && ic->prev == NULL) +#define IS_OP_GLOBALVOLATILE(x) (IS_OP_GLOBAL( x ) && isOpVolatile( x )) +#define LOCAL_POINTER (!IS_OP_GLOBAL(result) && !isOpVolatile(result) && OP_LIVEFROM(result) == 0 && OP_LIVETO(result) == 0) +#define ASSIGN_OPT(x,y) ( !IS_OP_GLOBAL( y ) && \ + !IS_OP_VOLATILE(x) && !IS_OP_VOLATILE(y) && \ + OP_LIVETO(y) != 0 && ic->seq >= OP_LIVETO(y)) + + +#define MULUSCHAR "_muluchar" +#define MULSCHAR "_mulschar" +#define MULINT "_mulint" +#define MULLONG "_mullong" +#define DIVSCHAR "_divschar" +#define DIVUSCHAR "_divuchar" +#define DIVSINT "_divsint" +#define DIVUSINT "_divuint" +#define DIVSLONG "_divslong" +#define DIVUSLONG "_divulong" +#define MODSCHAR "_modschar" +#define MODUSCHAR "_moduchar" +#define MODSINT "_modsint" +#define MODUSINT "_moduint" +#define MODSLONG "_modslong" +#define MODUSLONG "_modulong" + + +enum { + AOP_LIT = 1, + AOP_REG, AOP_DIR, + AOP_STK, AOP_STR +}; + +/* type asmop : a homogenised type for + all the different spaces an operand can be + in */ +typedef struct asmop { + + short type; /* can have values + AOP_LIT - operand is a literal value + AOP_REG - must be loaded into a register + AOP_DIR - direct just a name + + */ + short coff; /* current offset */ + short size; /* total size */ + unsigned freed:1; /* already freed */ + union { + value *aop_lit; /* if literal */ + reg_info *aop_reg[4]; /* array of registers */ + char *aop_dir; /* if direct */ + } aopu; +} asmop; + + +typedef struct inOutStruct { + char *name; /* IN/OUT operand name */ + operand *tempOper; + int liveFrom; + int liveTo; + short isNumOffset; /* port address given as a number or an operand */ + unsigned long numOffset; /* port address given as a number */ + operand *regOffset; /* port address given as an indirect operand */ +} inOutStruct_t; + +void testOp(operand * oper); + +void genPBLAZECode(iCode *); +void pblaze_emitDebuggerSymbol(const char *); +bool pblaze_operandsEqu(operand * op1, operand * op2); +int isOpVolatile(operand * oper); +void setRegUsed(int r); +int isRegUsed(int r); +short isCalleesaves(void); +void pushStack(int rdx, int c); + +void emitStore(char *r, int mem); +void emitStoreReg(char *r, char *adr); +void emitFetch(char *r, int mem); +void emitLoadNumb(char *r, int val); +void emitLoad(char *l, char *r); +void emitcodeADD(char *l, int val); +void emitcodeSUB(char *l, int val); + +int isInOutRef(operand * oper); +void pblaze_emitcodeOutput(iCode * ic, char *source, operand * to); + +void genMulDivFunc(FILE * of); + +void genMultChar(FILE * of); +void genMultUnsignedChar(FILE * of); +void genMultInt(FILE * of); +void genMultLong(FILE * of); +void genDivChar(FILE * of); +void genDivUnsignedChar(FILE * of); +void genModChar(FILE * of); +void genModUnsignedChar(FILE * of); +void genDivInt(FILE * of); +void genDivUnsignedInt(FILE * of); +void genModInt(FILE * of); +void genModUnsignedInt(FILE * of); +void genDivLong(FILE * of); +void genDivUnsignedLong(FILE * of); +void genModLong(FILE * of); +void genModUnsignedLong(FILE * of); +#endif diff -NaurbB sdcc-src-3.1.0/src/pblaze/genmuldiv.c sdcc-src-3.1.0-pblaze/src/pblaze/genmuldiv.c --- sdcc-src-3.1.0/src/pblaze/genmuldiv.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/pblaze/genmuldiv.c 2011-08-23 15:56:30.000000000 +0200 @@ -0,0 +1,685 @@ +/*------------------------------------------------------------------------- +genmuldiv.c - source file for code generation of MUL/DIV operations for + XILINX PICOBLAZE + +Author: + Jakub Hornik, xhorni00<at>stud.fit.vutbr.cz +Master Thesis Project: + Compiler Back-End of Subset of Language C for 8-Bit Processor +Date: + 2011 + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +In other words, you are welcome to use, share and improve this program. +You are forbidden to forbid anyone else to use, share and improve +what you give them. Help stamp out software-hoarding! + +-------------------------------------------------------------------------*/ + +#define LBL_KEY(x) x->key+10 + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include "SDCCglobl.h" +#include "newalloc.h" + +#include "common.h" +#include "ralloc.h" +#include "main.h" +#include "gen.h" + + +/*-----------------------------------------------------------------*/ +/* genMultChar - mult function 1B x 1B -> 2B */ +/*-----------------------------------------------------------------*/ +void genMultChar(FILE * of) +{ + symbol *lbls1 = newiTempLabel(NULL); + symbol *lbls2 = newiTempLabel(NULL); + symbol *lblend = newiTempLabel(NULL); + + fprintf(of, "\n"); + fprintf(of, "__mulschar:\n"); + fprintf(of, "\tLOAD\tsA, %s00\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tTEST\tsB, %s80\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tJUMP\tZ, _LM%04d\n", LBL_KEY(lbls1)); + fprintf(of, "\tXOR\tsB, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADD\tsB, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tLOAD\tsA, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "_LM%04d:\n", LBL_KEY(lbls1)); + fprintf(of, "\tTEST\tsC, %s80\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tJUMP\tZ, _LM%04d\n", LBL_KEY(lbls2)); + fprintf(of, "\tXOR\tsC, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADD\tsC, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tXOR\tsA, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "_LM%04d:\n", LBL_KEY(lbls2)); + fprintf(of, "\tCALL\t__muluchar\n"); + fprintf(of, "\tTEST\tsA, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tJUMP\tZ, _LM%04d\n", LBL_KEY(lblend)); + fprintf(of, "\tXOR\tsB, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tXOR\tsC, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADD\tsB, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADDC%s\tsC, %s00\n", pblaze_options.dialect ? "Y" : "", pblaze_options.dialect ? "" : "$"); + fprintf(of, "_LM%04d:\n", LBL_KEY(lblend)); + if (pblaze_options.dialect) + fprintf(of, "\tRETURN\n"); + else + fprintf(of, "\tRET\n"); +} + + +/*-----------------------------------------------------------------*/ +/* genMultUnsignedChar - mult function 1B x 1B -> 2B */ +/*-----------------------------------------------------------------*/ +void genMultUnsignedChar(FILE * of) +{ + symbol *lbladd = newiTempLabel(NULL); + symbol *lblc = newiTempLabel(NULL); + + fprintf(of, "\n"); + fprintf(of, "__muluchar:\n"); + fprintf(of, "\tLOAD\tsE, %s08\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tLOAD\tsD, sC\n"); + fprintf(of, "\tLOAD\tsC, %s00\n", pblaze_options.dialect ? "" : "$"); + + fprintf(of, "_LM%04d:\n", LBL_KEY(lblc)); + fprintf(of, "\tTEST\tsB, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tJUMP\tZ, _LM%04d\n", LBL_KEY(lbladd)); + fprintf(of, "\tADD\tsC, sD\n"); + + fprintf(of, "_LM%04d:\n", LBL_KEY(lbladd)); + fprintf(of, "\tSR0\tsC\n"); + fprintf(of, "\tSRA\tsB\n"); + fprintf(of, "\tSUB\tsE, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tJUMP\tNZ, _LM%04d\n", LBL_KEY(lblc)); + if (pblaze_options.dialect) + fprintf(of, "\tRETURN\n"); + else + fprintf(of, "\tRET\n"); +} + + +/*-----------------------------------------------------------------*/ +/* genMultInt - signed & unsigned 2B x 2B -> 2B */ +/*-----------------------------------------------------------------*/ +void genMultInt(FILE * of) +{ + + symbol *lbladd = newiTempLabel(NULL); + symbol *lblc = newiTempLabel(NULL); + + fprintf(of, "\n"); + fprintf(of, "__mulint:\n"); + fprintf(of, "\tLOAD\ts7, %s10\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tLOAD\ts8, sD\n"); + fprintf(of, "\tLOAD\ts9, sE\n"); + fprintf(of, "\tLOAD\tsD, %s00\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tLOAD\tsE, %s00\n", pblaze_options.dialect ? "" : "$"); + + fprintf(of, "_LM%04d:\n", LBL_KEY(lblc)); + fprintf(of, "\tTEST\tsB, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tJUMP\tZ, _LM%04d\n", LBL_KEY(lbladd)); + fprintf(of, "\tADD\tsD, s8\n"); + fprintf(of, "\tADDC%s\tsE, s9\n", pblaze_options.dialect ? "Y" : ""); + + fprintf(of, "_LM%04d:\n", LBL_KEY(lbladd)); + fprintf(of, "\tSR0\tsE\n"); + fprintf(of, "\tSRA\tsD\n"); + fprintf(of, "\tSRA\tsC\n"); + fprintf(of, "\tSRA\tsB\n"); + + fprintf(of, "\tSUB\ts7, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tJUMP\tNZ, _LM%04d\n", LBL_KEY(lblc)); + if (pblaze_options.dialect) + fprintf(of, "\tRETURN\n"); + else + fprintf(of, "\tRET\n"); +} + + + +/*-----------------------------------------------------------------*/ +/* genMultLong - signed & unsigned 4B x 4B -> 4B */ +/*-----------------------------------------------------------------*/ +void genMultLong(FILE * of) +{ + symbol *lbladd = newiTempLabel(NULL); + symbol *lblc = newiTempLabel(NULL); + + fprintf(of, "\n"); + fprintf(of, "__mullong:\n"); + + // load multiplicand, multiplier is stored in registers sE..sB + fprintf(of, "\tADD\tsF, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tFETCH\ts6, (sF)\n"); + fprintf(of, "\tADD\tsF, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tFETCH\ts5, (sF)\n"); + fprintf(of, "\tADD\tsF, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tFETCH\ts4, (sF)\n"); + fprintf(of, "\tADD\tsF, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tFETCH\ts3, (sF)\n"); + + // 32 cycles + fprintf(of, "\tLOAD\ts2, %s20\n", pblaze_options.dialect ? "" : "$"); + + // clear upper 4B of the result (but only lower 4B are used as the result) + fprintf(of, "\tLOAD\tsA, %s00\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tLOAD\ts9, %s00\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tLOAD\ts8, %s00\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tLOAD\ts7, %s00\n", pblaze_options.dialect ? "" : "$"); + + fprintf(of, "_LM%04d:\n", LBL_KEY(lblc)); + // add multiplicand to the result if the lowest bit of the multiplier is 1 + fprintf(of, "\tTEST\tsB, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tJUMP\tZ, _LM%04d\n", LBL_KEY(lbladd)); + fprintf(of, "\tADD\ts7, s3\n"); + fprintf(of, "\tADDC%s\ts8, s4\n", pblaze_options.dialect ? "Y" : ""); + fprintf(of, "\tADDC%s\ts9, s5\n", pblaze_options.dialect ? "Y" : ""); + fprintf(of, "\tADDC%s\tsA, s6\n", pblaze_options.dialect ? "Y" : ""); + + // result is shifted right + fprintf(of, "_LM%04d:\n", LBL_KEY(lbladd)); + fprintf(of, "\tSR0\tsA\n"); + fprintf(of, "\tSRA\ts9\n"); + fprintf(of, "\tSRA\ts8\n"); + fprintf(of, "\tSRA\ts7\n"); + fprintf(of, "\tSRA\tsE\n"); + fprintf(of, "\tSRA\tsD\n"); + fprintf(of, "\tSRA\tsC\n"); + fprintf(of, "\tSRA\tsB\n"); + + fprintf(of, "\tSUB\ts2, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tJUMP\tNZ, _LM%04d\n", LBL_KEY(lblc)); + if (pblaze_options.dialect) + fprintf(of, "\tRETURN\n"); + else + fprintf(of, "\tRET\n"); +} + +/*-----------------------------------------------------------------*/ +/* genModChar - function 1B mod 1B -> 1B */ +/*-----------------------------------------------------------------*/ +void genModChar(FILE * of) +{ + + symbol *lblend = newiTempLabel(NULL); + + fprintf(of, "\n"); + fprintf(of, "__modschar:\n"); + fprintf(of, "\tCALL\t__divschar\n"); + fprintf(of, "\tTEST\tsA, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tJUMP\tZ, _LM%04d\n", LBL_KEY(lblend)); + fprintf(of, "\tXOR\tsC, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADD\tsC, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "_LM%04d:\n", LBL_KEY(lblend)); + fprintf(of, "\tXOR\tsB, sC\n"); + fprintf(of, "\tXOR\tsC, sB\n"); + fprintf(of, "\tXOR\tsB, sC\n"); + if (pblaze_options.dialect) + fprintf(of, "\tRETURN\n"); + else + fprintf(of, "\tRET\n"); +} + +/*-----------------------------------------------------------------*/ +/* genModUnsignedChar - mod function 1B / 1B -> 1B */ +/*-----------------------------------------------------------------*/ +void genModUnsignedChar(FILE * of) +{ + + fprintf(of, "\n"); + fprintf(of, "__moduchar:\n"); + fprintf(of, "__moduschar:\n"); + fprintf(of, "\tCALL\t__divuschar\n"); + + fprintf(of, "\tXOR\tsB, sC\n"); + fprintf(of, "\tXOR\tsC, sB\n"); + fprintf(of, "\tXOR\tsB, sC\n"); + if (pblaze_options.dialect) + fprintf(of, "\tRETURN\n"); + else + fprintf(of, "\tRET\n"); +} + +/*-----------------------------------------------------------------*/ +/* genDivChar - Div function 1B / 1B -> 1B */ +/*-----------------------------------------------------------------*/ +void genDivChar(FILE * of) +{ + + symbol *lblend = newiTempLabel(NULL); + symbol *lbls1 = newiTempLabel(NULL); + symbol *lbls2 = newiTempLabel(NULL); + + fprintf(of, "\n"); + fprintf(of, "__divschar:\n"); + fprintf(of, "\tLOAD\tsA, %s00\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tTEST\tsB, %s80\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tJUMP\tZ, _LM%04d\n", LBL_KEY(lbls1)); + fprintf(of, "\tXOR\tsB, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADD\tsB, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tOR\tsA, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "_LM%04d:\n", LBL_KEY(lbls1)); + fprintf(of, "\tTEST\tsC, %s80\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tJUMP\tZ, _LM%04d\n", LBL_KEY(lbls2)); + fprintf(of, "\tXOR\tsC, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADD\tsC, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tOR\tsA, %s02\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "_LM%04d:\n", LBL_KEY(lbls2)); + fprintf(of, "\tCALL\t__divuchar\n"); + fprintf(of, "\tTEST\tsA, %s03\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tJUMP\tNC, _LM%04d\n", LBL_KEY(lblend)); + fprintf(of, "\tXOR\tsB, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADD\tsB, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "_LM%04d:\n", LBL_KEY(lblend)); + if (pblaze_options.dialect) + fprintf(of, "\tRETURN\n"); + else + fprintf(of, "\tRET\n"); +} + +/*-----------------------------------------------------------------*/ +/* genDivUnsignedChar - mDiv function 1B / 1B -> 1B */ +/*-----------------------------------------------------------------*/ +void genDivUnsignedChar(FILE * of) +{ + symbol *lblc = newiTempLabel(NULL); + symbol *lbladd = newiTempLabel(NULL); + + fprintf(of, "\n"); + fprintf(of, "__divuchar:\n"); + fprintf(of, "\tLOAD\tsE, %s08\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tLOAD\tsD, sC\n"); + fprintf(of, "\tLOAD\tsC, %s00\n", pblaze_options.dialect ? "" : "$"); + + fprintf(of, "_LM%04d:\n", LBL_KEY(lblc)); + fprintf(of, "\tSL0\tsB\n"); + fprintf(of, "\tSLA\tsC\n"); + fprintf(of, "\tCOMP%s\tsC, sD\n", pblaze_options.dialect ? "ARE" : ""); + fprintf(of, "\tJUMP\tC, _LM%04d\n", LBL_KEY(lbladd)); + fprintf(of, "\tSUB\tsC, sD\n"); + fprintf(of, "\tADD\tsB, %s01\n", pblaze_options.dialect ? "" : "$"); + + fprintf(of, "_LM%04d:\n", LBL_KEY(lbladd)); + + fprintf(of, "\tSUB\tsE, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tJUMP\tNZ, _LM%04d\n", LBL_KEY(lblc)); + if (pblaze_options.dialect) + fprintf(of, "\tRETURN\n"); + else + fprintf(of, "\tRET\n"); +} + + +/*-----------------------------------------------------------------*/ +/* genModInt */ +/*-----------------------------------------------------------------*/ +void genModInt(FILE * of) +{ + + symbol *lblend = newiTempLabel(NULL); + + fprintf(of, "\n"); + fprintf(of, "__modsint:\n"); + fprintf(of, "\tCALL\t__divsint\n"); + fprintf(of, "\tTEST\tsA, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tJUMP\tZ, _LM%04d\n", LBL_KEY(lblend)); + fprintf(of, "\tXOR\tsD, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tXOR\tsE, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADD\tsD, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADDC%s\tsE, %s00\n", pblaze_options.dialect ? "Y" : "", pblaze_options.dialect ? "" : "$"); + + fprintf(of, "_LM%04d:\n", LBL_KEY(lblend)); + fprintf(of, "\tXOR\tsB, sD\n"); + fprintf(of, "\tXOR\tsD, sB\n"); + fprintf(of, "\tXOR\tsB, sD\n"); + + fprintf(of, "\tXOR\tsE, sC\n"); + fprintf(of, "\tXOR\tsC, sE\n"); + fprintf(of, "\tXOR\tsE, sC\n"); + if (pblaze_options.dialect) + fprintf(of, "\tRETURN\n"); + else + fprintf(of, "\tRET\n"); +} + +/*-----------------------------------------------------------------*/ +/* genModUnsignedInt */ +/*-----------------------------------------------------------------*/ +void genModUnsignedInt(FILE * of) +{ + + fprintf(of, "\n"); + fprintf(of, "__moduint:\n"); + fprintf(of, "\tCALL\t__divuint\n"); + + fprintf(of, "\tXOR\tsB, sD\n"); + fprintf(of, "\tXOR\tsD, sB\n"); + fprintf(of, "\tXOR\tsB, sD\n"); + + fprintf(of, "\tXOR\tsE, sC\n"); + fprintf(of, "\tXOR\tsC, sE\n"); + fprintf(of, "\tXOR\tsE, sC\n"); + + if (pblaze_options.dialect) + fprintf(of, "\tRETURN\n"); + else + fprintf(of, "\tRET\n"); +} + +/*-----------------------------------------------------------------*/ +/* genDivInt */ +/*-----------------------------------------------------------------*/ +void genDivInt(FILE * of) +{ + + symbol *lblend = newiTempLabel(NULL); + symbol *lbls1 = newiTempLabel(NULL); + symbol *lbls2 = newiTempLabel(NULL); + + fprintf(of, "\n"); + fprintf(of, "__divsint:\n"); + fprintf(of, "\tLOAD\tsA, %s00\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tTEST\tsC, %s80\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tJUMP\tZ, _LM%04d\n", LBL_KEY(lbls1)); + fprintf(of, "\tXOR\tsB, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tXOR\tsC, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADD\tsB, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADDC%s\tsC, %s00\n", pblaze_options.dialect ? "Y" : "", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tOR\tsA, %s01\n", pblaze_options.dialect ? "" : "$"); + + fprintf(of, "_LM%04d:\n", LBL_KEY(lbls1)); + fprintf(of, "\tTEST\tsE, %s80\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tJUMP\tZ, _LM%04d\n", LBL_KEY(lbls2)); + fprintf(of, "\tXOR\tsD, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tXOR\tsE, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADD\tsD, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADDC%s\tsE, %s00\n", pblaze_options.dialect ? "Y" : "", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tOR\tsA, %s02\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "_LM%04d:\n", LBL_KEY(lbls2)); + fprintf(of, "\tCALL\t__divuint\n"); + fprintf(of, "\tTEST\tsA, %s03\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tJUMP\tNC, _LM%04d\n", LBL_KEY(lblend)); + fprintf(of, "\tXOR\tsB, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tXOR\tsC, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADD\tsB, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADDC%s\tsC, %s00\n", pblaze_options.dialect ? "Y" : "", pblaze_options.dialect ? "" : "$"); + fprintf(of, "_LM%04d:\n", LBL_KEY(lblend)); + if (pblaze_options.dialect) + fprintf(of, "\tRETURN\n"); + else + fprintf(of, "\tRET\n"); +} + +/*-----------------------------------------------------------------*/ +/* genDivUnsignedInt */ +/*-----------------------------------------------------------------*/ +void genDivUnsignedInt(FILE * of) +{ + symbol *lblc = newiTempLabel(NULL); + symbol *lbladd = newiTempLabel(NULL); + + fprintf(of, "\n"); + fprintf(of, "__divuint:\n"); + fprintf(of, "\tLOAD\ts7, %s10\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tLOAD\ts8, sD\n"); + fprintf(of, "\tLOAD\ts9, sE\n"); + fprintf(of, "\tLOAD\tsD, %s00\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tLOAD\tsE, %s00\n", pblaze_options.dialect ? "" : "$"); + + fprintf(of, "_LM%04d:\n", LBL_KEY(lblc)); + fprintf(of, "\tSL0\tsB\n"); + fprintf(of, "\tSLA\tsC\n"); + fprintf(of, "\tSLA\tsD\n"); + fprintf(of, "\tSLA\tsE\n"); + + fprintf(of, "\tCOMP%s\tsE, s9\n", pblaze_options.dialect ? "ARE" : ""); + fprintf(of, "\tJUMP\tC, _LM%04d\n", LBL_KEY(lbladd)); + fprintf(of, "\tCOMP%s\tsD, s8\n", pblaze_options.dialect ? "ARE" : ""); + fprintf(of, "\tJUMP\tC, _LM%04d\n", LBL_KEY(lbladd)); + + fprintf(of, "\tSUB\tsD, s8\n"); + fprintf(of, "\tSUBC%s\tsE, s9\n", pblaze_options.dialect ? "Y" : ""); + fprintf(of, "\tADD\tsB, %s01\n", pblaze_options.dialect ? "" : "$"); + + fprintf(of, "_LM%04d:\n", LBL_KEY(lbladd)); + + fprintf(of, "\tSUB\ts7, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tJUMP\tNZ, _LM%04d\n", LBL_KEY(lblc)); + if (pblaze_options.dialect) + fprintf(of, "\tRETURN\n"); + else + fprintf(of, "\tRET\n"); +} + +/*-----------------------------------------------------------------*/ +/* genDivUnsignedLong - signed & unsigned 4B x 4B -> 4B */ +/*-----------------------------------------------------------------*/ +void genDivUnsignedLong(FILE * of) +{ + symbol *lbladd = newiTempLabel(NULL); + symbol *lbldo = newiTempLabel(NULL); + symbol *lblc = newiTempLabel(NULL); + + fprintf(of, "\n"); + fprintf(of, "__divulong:\n"); + + fprintf(of, "\tCALL\t__divuslongload\n"); + fprintf(of, "\tCALL\t__divuslongdiv\n"); + if (pblaze_options.dialect) + fprintf(of, "\tRETURN\n"); + else + fprintf(of, "\tRET\n"); + + fprintf(of, "__divuslongdiv:\n"); + // 32 cycles + fprintf(of, "\tLOAD\ts2, %s20\n", pblaze_options.dialect ? "" : "$"); + + // clear upper 4B of the result (but only lower 4B are used as the result) + fprintf(of, "\tLOAD\tsA, %s00\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tLOAD\ts9, %s00\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tLOAD\ts8, %s00\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tLOAD\ts7, %s00\n", pblaze_options.dialect ? "" : "$"); + + fprintf(of, "_LM%04d:\n", LBL_KEY(lblc)); + // result is shifted left + fprintf(of, "\tSL0\tsB\n"); + fprintf(of, "\tSLA\tsC\n"); + fprintf(of, "\tSLA\tsD\n"); + fprintf(of, "\tSLA\tsE\n"); + fprintf(of, "\tSLA\ts7\n"); + fprintf(of, "\tSLA\ts8\n"); + fprintf(of, "\tSLA\ts9\n"); + fprintf(of, "\tSLA\tsA\n"); + + fprintf(of, "\tCOMP%s\tsA, s6\n", pblaze_options.dialect ? "ARE" : ""); + fprintf(of, "\tJUMP\tC, _LM%04d\n", LBL_KEY(lbladd)); + fprintf(of, "\tJUMP\tNZ, _LM%04d\n", LBL_KEY(lbldo)); + fprintf(of, "\tCOMP%s\ts9, s5\n", pblaze_options.dialect ? "ARE" : ""); + fprintf(of, "\tJUMP\tC, _LM%04d\n", LBL_KEY(lbladd)); + fprintf(of, "\tJUMP\tNZ, _LM%04d\n", LBL_KEY(lbldo)); + fprintf(of, "\tCOMP%s\ts8, s4\n", pblaze_options.dialect ? "ARE" : ""); + fprintf(of, "\tJUMP\tC, _LM%04d\n", LBL_KEY(lbladd)); + fprintf(of, "\tJUMP\tNZ, _LM%04d\n", LBL_KEY(lbldo)); + fprintf(of, "\tCOMP%s\ts7, s3\n", pblaze_options.dialect ? "ARE" : ""); + fprintf(of, "\tJUMP\tC, _LM%04d\n", LBL_KEY(lbladd)); + + fprintf(of, "_LM%04d:\n", LBL_KEY(lbldo)); + fprintf(of, "\tSUB\ts7, s3\n"); + fprintf(of, "\tSUBC%s\ts8, s4\n", pblaze_options.dialect ? "Y" : ""); + fprintf(of, "\tSUBC%s\ts9, s5\n", pblaze_options.dialect ? "Y" : ""); + fprintf(of, "\tSUBC%s\tsA, s6\n", pblaze_options.dialect ? "Y" : ""); + fprintf(of, "\tADD\tsB, %s01\n", pblaze_options.dialect ? "" : "$"); + + fprintf(of, "_LM%04d:\n", LBL_KEY(lbladd)); + + fprintf(of, "\tSUB\ts2, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tJUMP\tNZ, _LM%04d\n", LBL_KEY(lblc)); + if (pblaze_options.dialect) + fprintf(of, "\tRETURN\n"); + else + fprintf(of, "\tRET\n"); + + fprintf(of, "__divuslongload:\n"); + // load divisor, divident is stored in registers sE..sB + fprintf(of, "\tADD\tsF, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tFETCH\ts6, (sF)\n"); + fprintf(of, "\tADD\tsF, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tFETCH\ts5, (sF)\n"); + fprintf(of, "\tADD\tsF, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tFETCH\ts4, (sF)\n"); + fprintf(of, "\tADD\tsF, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tFETCH\ts3, (sF)\n"); + if (pblaze_options.dialect) + fprintf(of, "\tRETURN\n"); + else + fprintf(of, "\tRET\n"); +} + +/*-----------------------------------------------------------------*/ +/* genDivLong - */ +/*-----------------------------------------------------------------*/ +void genDivLong(FILE * of) +{ + + symbol *lblend = newiTempLabel(NULL); + symbol *lbls1 = newiTempLabel(NULL); + symbol *lbls2 = newiTempLabel(NULL); + + fprintf(of, "\n"); + fprintf(of, "__divslong:\n"); + fprintf(of, "\tCALL\t__divuslongload\n"); + fprintf(of, "\tLOAD\tsA, %s00\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tTEST\tsC, %s80\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tJUMP\tZ, _LM%04d\n", LBL_KEY(lbls1)); + fprintf(of, "\tXOR\tsB, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tXOR\tsC, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tXOR\tsD, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tXOR\tsE, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADD\tsB, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADDC%s\tsC, %s00\n", pblaze_options.dialect ? "Y" : "", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADDC%s\tsD, %s00\n", pblaze_options.dialect ? "Y" : "", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADDC%s\tsE, %s00\n", pblaze_options.dialect ? "Y" : "", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tOR\tsA, %s01\n", pblaze_options.dialect ? "" : "$"); + + fprintf(of, "_LM%04d:\n", LBL_KEY(lbls1)); + fprintf(of, "\tTEST\tsE, %s80\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tJUMP\tZ, _LM%04d\n", LBL_KEY(lbls2)); + fprintf(of, "\tXOR\ts3, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tXOR\ts4, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tXOR\ts5, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tXOR\ts6, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADD\ts3, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADDC%s\ts4, %s00\n", pblaze_options.dialect ? "Y" : "", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADDC%s\ts5, %s00\n", pblaze_options.dialect ? "Y" : "", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADDC%s\ts6, %s00\n", pblaze_options.dialect ? "Y" : "", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tOR\tsA, %s02\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "_LM%04d:\n", LBL_KEY(lbls2)); + fprintf(of, "\tCALL\t__divuslongdiv\n"); + fprintf(of, "\tTEST\tsA, %s03\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tJUMP\tNC, _LM%04d\n", LBL_KEY(lblend)); + fprintf(of, "\tXOR\tsB, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tXOR\tsC, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tXOR\tsD, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tXOR\tsE, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADD\tsB, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADDC%s\tsC, %s00\n", pblaze_options.dialect ? "Y" : "", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADDC%s\tsD, %s00\n", pblaze_options.dialect ? "Y" : "", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADDC%s\tsE, %s00\n", pblaze_options.dialect ? "Y" : "", pblaze_options.dialect ? "" : "$"); + fprintf(of, "_LM%04d:\n", LBL_KEY(lblend)); + if (pblaze_options.dialect) + fprintf(of, "\tRETURN\n"); + else + fprintf(of, "\tRET\n"); +} + +/*-----------------------------------------------------------------*/ +/* genModLong - mod function 4B / 4B -> 4B */ +/*-----------------------------------------------------------------*/ +void genModLong(FILE * of) +{ + + symbol *lblend = newiTempLabel(NULL); + + fprintf(of, "\n"); + fprintf(of, "__modslong:\n"); + fprintf(of, "\tCALL\t__divslong\n"); + fprintf(of, "\tTEST\tsA, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tJUMP\tZ, _LM%04d\n", LBL_KEY(lblend)); + fprintf(of, "\tXOR\ts7, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tXOR\ts8, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tXOR\ts9, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tXOR\tsA, %sFF\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADD\ts7, %s01\n", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADDC%s\ts8, %s00\n", pblaze_options.dialect ? "Y" : "", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADDC%s\ts9, %s00\n", pblaze_options.dialect ? "Y" : "", pblaze_options.dialect ? "" : "$"); + fprintf(of, "\tADDC%s\tsA, %s00\n", pblaze_options.dialect ? "Y" : "", pblaze_options.dialect ? "" : "$"); + + fprintf(of, "_LM%04d:\n", LBL_KEY(lblend)); + fprintf(of, "\tXOR\tsB, s7\n"); + fprintf(of, "\tXOR\ts7, sB\n"); + fprintf(of, "\tXOR\tsB, s7\n"); + + fprintf(of, "\tXOR\ts8, sC\n"); + fprintf(of, "\tXOR\tsC, s8\n"); + fprintf(of, "\tXOR\ts8, sC\n"); + + fprintf(of, "\tXOR\tsD, s9\n"); + fprintf(of, "\tXOR\ts9, sD\n"); + fprintf(of, "\tXOR\tsD, s9\n"); + + fprintf(of, "\tXOR\tsE, sA\n"); + fprintf(of, "\tXOR\tsA, sE\n"); + fprintf(of, "\tXOR\tsE, sA\n"); + if (pblaze_options.dialect) + fprintf(of, "\tRETURN\n"); + else + fprintf(of, "\tRET\n"); +} + +/*-----------------------------------------------------------------*/ +/* genModUnsignedLong - mod function 4B / 4B -> 4B */ +/*-----------------------------------------------------------------*/ +void genModUnsignedLong(FILE * of) +{ + + fprintf(of, "\n"); + fprintf(of, "__modulong:\n"); + fprintf(of, "\tCALL\t__divulong\n"); + + fprintf(of, "\tXOR\tsB, s7\n"); + fprintf(of, "\tXOR\ts7, sB\n"); + fprintf(of, "\tXOR\tsB, s7\n"); + + fprintf(of, "\tXOR\ts8, sC\n"); + fprintf(of, "\tXOR\tsC, s8\n"); + fprintf(of, "\tXOR\ts8, sC\n"); + + fprintf(of, "\tXOR\tsD, s9\n"); + fprintf(of, "\tXOR\ts9, sD\n"); + fprintf(of, "\tXOR\tsD, s9\n"); + + fprintf(of, "\tXOR\tsE, sA\n"); + fprintf(of, "\tXOR\tsA, sE\n"); + fprintf(of, "\tXOR\tsE, sA\n"); + + if (pblaze_options.dialect) + fprintf(of, "\tRETURN\n"); + else + fprintf(of, "\tRET\n"); +} diff -NaurbB sdcc-src-3.1.0/src/pblaze/main.c sdcc-src-3.1.0-pblaze/src/pblaze/main.c --- sdcc-src-3.1.0/src/pblaze/main.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/pblaze/main.c 2011-12-06 01:42:51.714771500 +0100 @@ -0,0 +1,355 @@ +/** @file main.c + pblaze specific general functions. + + Author: + Jakub Hornik, xhorni00<at>stud.fit.vutbr.cz + Master Thesis Project: + Compiler Back-End of Subset of Language C for 8-Bit Processor + Date: + 2011 + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ + +#include "common.h" +#include "main.h" +#include "ralloc.h" +#include "gen.h" +#include "ralloc.h" +#include "pbglue.h" +#include "dbuf_string.h" + +static char _defaultRules[] = { +#include "peeph.rul" +}; + +#define DIALECT_OPT "--dialect=" +#define PORTKW_OPT "--portkw=" +#define ACKNOWLEDGEMENT_OPT "--acknowledgement" + +pblaze_options_t pblaze_options; + +OPTION pblaze_optionsTable[] = { + {0, DIALECT_OPT, &pblaze_options.dialect, + "(kcpsm3 or pblazeide) selects the assembler dialect for the chosen target platform (see argument --target) as there are some minor differences between the PicoBlaze-3 Assembler for HDL/HEX production (KCPSM3) and for the simulation (pBlazeIDE). (Default: pblazeide)"}, + {0, PORTKW_OPT, &pblaze_options.portKw, + "set proper keyword used for INPUT/OUTPUT operations (default: PBLAZEPORT)"}, + {0, ACKNOWLEDGEMENT_OPT, NULL, + "The development of this pblaze-port was supported by the Czech Ministry of Education, Youth and Sports grant 2C06008 Virtual Laboratory of Microprocessor Technology Application (visit the website http://www.vlam.cz)."}, + {0, NULL, NULL, NULL} +}; + +/* list of key words used by msc51 */ +static char *_pblaze_keywords[] = { + "at", + "code", + "critical", + "interrupt", + "xdata", + "_code", + "_generic", + "_xdata", + "_NECO", + NULL +}; + +static int regParmFlg = 0; /* determine if we can register a parameter */ + +static void _pblaze_init(void) +{ + asm_addTree(&asm_asxxxx_mapping); +} + +static void _pblaze_reset_regparm(void) +{ + regParmFlg = 0; +} + + +void _pblaze_genInitStartup(FILE * of) +{ + printConstants(of); +} + + +static int _pblaze_regparm(sym_link * l, bool reentrant) +{ + /* we won't split variables + i.e. if not enough registers left to hold + the parameter then the whole parameter along + with rest of the parameters go onto the stack */ + if (regParmFlg < SEND_REG_COUNT) { + int size; + if ((size = getSize(l)) > (SEND_REG_COUNT - regParmFlg)) { + /* all remaining go on stack */ + regParmFlg = SEND_REG_COUNT; + return 0; + } + regParmFlg += size; + return 1; + } + + return 0; +} + +void pblaze_assignRegisters(ebbIndex *); + +#define ISOPT(str) !strncmp(argv[ *i ], str, strlen(str) ) + +static bool _pblaze_parseOptions(int *pargc, char **argv, int *i) +{ + char *dialecttype; + + if (ISOPT(DIALECT_OPT)) { + dialecttype = getStringArg(DIALECT_OPT, argv, i, *pargc); + if (!STRCASECMP(dialecttype, "pblazeide")) + pblaze_options.dialect = 0; + else if (!STRCASECMP(dialecttype, "kcpsm3")) + pblaze_options.dialect = 1; + else { + fprintf(stderr, "Unknown dialect type: %s\nAvaiable options: pblazeide or kcpsm3\n", dialecttype); + exit(EXIT_FAILURE); + } + return TRUE; + } + + if (ISOPT(PORTKW_OPT)) { + pblaze_options.portKw = Safe_strdup(getStringArg(PORTKW_OPT, argv, i, *pargc)); + return TRUE; + } + + if (ISOPT(ACKNOWLEDGEMENT_OPT)) { + fprintf(stderr, "The development of this pblaze-port was supported by the Czech Ministry of Education, Youth and Sports grant 2C06008 Virtual Laboratory of Microprocessor Technology Application (visit the website http://www.vlam.cz)."); + exit(EXIT_FAILURE); + return TRUE; + } + + return FALSE; +} + + +static void _pblaze_finaliseOptions(void) +{ + port->mem.default_local_map = port->mem.default_globl_map = data; + /* change stack to be in far space */ + /* internal stack segment ; + SFRSPACE - NO + FAR-SPACE - YES + PAGED - NO + DIRECT-ACCESS - NO + BIT-ACCESS - NO + CODE-ACESS - NO + DEBUG-NAME - 'B' + POINTER-TYPE - FPOINTER + */ + istack = allocMap(0, 1, 0, 0, 0, 0, options.stack_loc, ISTACK_NAME, 'B', FPOINTER); + + /* also change xdata to be direct space since we can use lds/sts */ + xdata->direct = 1; + +} + +static void _pblaze_setDefaultOptions(void) +{ + pblaze_options.dialect = 1; + pblaze_options.portKw = "PBLAZEPORT"; + options.stackAuto = 1; +} + +static const char *_pblaze_getRegName(struct reg_info *reg) +{ + if (reg) + return reg->name; + return "err"; +} + +static void _pblaze_genAssemblerPreamble(FILE * of) +{ + +} + +static void _pblaze_genAssemblerEnd(FILE * of) +{ + genMulDivFunc(of); +} + +/* Generate interrupt vector table. */ +static int _pblaze_genIVT(struct dbuf_s *oBuf, symbol ** interrupts, int maxInterrupts) +{ + if (pblaze_interrupt) { + if (pblaze_options.dialect) { + dbuf_printf(oBuf, "\tADDRESS\t3ff\n"); + } else { + dbuf_printf(oBuf, "\tORG\t$3ff\n"); + } + dbuf_printf(oBuf, "\tJUMP\t_%s\n", pblaze_interrupt->name); + } + + return TRUE; +} + +/* Indicate which extended bit operations this port supports */ +static bool hasExtBitOp(int op, int size) +{ + if (op == RRC || op == RLC || op == GETHBIT) + return TRUE; + else + return FALSE; +} + +/* Indicate the expense of an access to an output storage class */ +static int oclsExpense(struct memmap *oclass) +{ + if (IN_FARSPACE(oclass)) + return 1; + + return 0; +} + +/** $1 is always the basename. + $2 is always the output file. + $3 varies + $l is the list of extra options that should be there somewhere... + MUST be terminated with a NULL. +*/ +static const char *_linkCmd[] = { + "linkpblaze", "", "\"$1\"", NULL +}; + +/* $3 is replaced by assembler.debug_opts resp. port->assembler.plain_opts */ +static const char *_asmCmd[] = { + "aspblaze", "$l", "$3", "\"$1.s\"", NULL +}; + +/* Globals */ +PORT pblaze_port = { + TARGET_ID_PBLAZE, + "pblaze", + "XILINX PicoBlaze", /* Target name */ + NULL, /* processor */ + { + pblaze_glue, + TRUE, /* Emit glue around main */ + MODEL_SMALL, + MODEL_SMALL, + NULL, /* model == target */ + }, + { + _asmCmd, + NULL, + "-plosgff", /* Options with debug */ + "-plosgff", /* Options without debug */ + 0, + ".psm", + NULL, /* no do_assemble */ + }, + { + _linkCmd, + NULL, + NULL, + ".rel", + 1}, + { + _defaultRules}, + { + /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */ + 1, 2, 2, 4, 1, 1, 1, 1, 0, 4}, + + /* tags for generic pointers */ + {0x00, 0x40, 0x60, 0x80}, /* far, near, xstack, code */ + + { + "XSEG", + "STACK", + "CSEG", + "DSEG", + "ISEG", + NULL, //PSEG + "XSEG", + "BSEG", + "RSEG", + "GSINIT", + "OSEG", + "GSFINAL", + "HOME", + NULL, // initialized xdata + NULL, // a code copy of xiseg + "CONST (CODE)", // const_name - const data (code or not) + "CABS (ABS,CODE)", // cabs_name - const absolute data (code or not) + "XABS (ABS,XDATA)", // xabs_name - absolute xdata/pdata + "IABS (ABS,DATA)", // iabs_name - absolute idata/data + NULL, + NULL, + 0, + }, + {NULL, NULL}, + { + -1, 1, 4, 1, 1, 0}, + /* pblaze hasn't any mul */ + { + 0, -1}, + { + pblaze_emitDebuggerSymbol}, + { + 32, /* maxCount */ + 2, /* sizeofElement */ + /* the behavior of src/SDCCicode.c 1.207 and earlier. */ + {2, 2, 2}, /* sizeofMatchJump[] */ + {0, 0, 0}, /* sizeofRangeCompare[] */ + 0, /* sizeofSubtract */ + 2, /* sizeofDispatch */ + }, + "_", + _pblaze_init, + _pblaze_parseOptions, + pblaze_optionsTable, + NULL, + _pblaze_finaliseOptions, + _pblaze_setDefaultOptions, + pblaze_assignRegisters, + _pblaze_getRegName, + _pblaze_keywords, + _pblaze_genAssemblerPreamble, + _pblaze_genAssemblerEnd, /* no genAssemblerEnd */ + _pblaze_genIVT, + NULL, // _pblaze_genXINIT + _pblaze_genInitStartup, /* genInitStartup */ + _pblaze_reset_regparm, + _pblaze_regparm, + NULL, + NULL, + NULL, + hasExtBitOp, /* hasExtBitOp */ + oclsExpense, /* oclsExpense */ + FALSE, + TRUE, /* little endian */ + 0, /* leave lt */ + 0, /* leave gt */ + 1, /* transform <= to ! > */ + 1, /* transform >= to ! < */ + 1, /* transform != to !(a == b) */ + 0, /* leave == */ + FALSE, /* No array initializer support. */ + 0, /* no CSE cost estimation yet */ + NULL, /* no builtin functions */ + GPOINTER, /* treat unqualified pointers as "generic" pointers */ + 0, /* reset labelKey to 1 */ + 1, /* globals & local static allowed */ + PORT_MAGIC +}; diff -NaurbB sdcc-src-3.1.0/src/pblaze/main.h sdcc-src-3.1.0-pblaze/src/pblaze/main.h --- sdcc-src-3.1.0/src/pblaze/main.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/pblaze/main.h 2011-08-23 15:56:30.000000000 +0200 @@ -0,0 +1,45 @@ +/*------------------------------------------------------------------------- +main.h - header file for XILINX PICOBLAZE + +Author: + Jakub Hornik, xhorni00<at>stud.fit.vutbr.cz +Master Thesis Project: + Compiler Back-End of Subset of Language C for 8-Bit Processor +Date: + 2011 + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ + +#ifndef MAIN_INCLUDE +#define MAIN_INCLUDE + +bool x_parseOptions(char **argv, int *pargc); +void x_setDefaultOptions(void); +void x_finaliseOptions(void); + +typedef struct { + int dialect; + char *portKw; +} pblaze_options_t; + +symbol *pblaze_interrupt; +extern pblaze_options_t pblaze_options; + +#endif diff -NaurbB sdcc-src-3.1.0/src/pblaze/pbglue.c sdcc-src-3.1.0-pblaze/src/pblaze/pbglue.c --- sdcc-src-3.1.0/src/pblaze/pbglue.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/pblaze/pbglue.c 2011-08-23 15:56:30.000000000 +0200 @@ -0,0 +1,677 @@ +/*------------------------------------------------------------------------- + pbglue.c - glues everything we have done together into one file. + Written By: + Sandeep Dutta . sandeep.dutta@usa.net (1998) + && + Jakub Hornik, xhorni00<at>stud.fit.vutbr.cz + Master Thesis Project: + Compiler Back-End of Subset of Language C for 8-Bit Processor + Date: + 2011 + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ + +#include "pbglue.h" +#include "main.h" +#include "ralloc.h" + +#include <time.h> +//#include "newalloc.h" +#include <fcntl.h> +#include <sys/stat.h> +#include "dbuf_string.h" + +#ifdef _WIN32 +#include <io.h> +#else +#include <unistd.h> +#endif + +symbol *interrupts[INTNO_MAX + 1]; + +void printIval(symbol *, sym_link *, initList *, struct dbuf_s *, bool check); +set *pblaze_publics = NULL; /* public variables */ +set *pblaze_externs = NULL; /* Variables that are declared as extern */ + +//unsigned maxInterrupts = 0; +int pblaze_allocInfo = 1; +symbol *pblaze_mainf; +int pblaze_noInit = 0; /* no initialization */ + + +/*-----------------------------------------------------------------*/ +/* pblaze_emitDebugSym - emit label for debug symbol */ +/*-----------------------------------------------------------------*/ +static void pblaze_emitDebugSym(struct dbuf_s *oBuf, symbol * sym) +{ + if (!sym->level) { /* global */ + if (IS_STATIC(sym->etype)) + dbuf_printf(oBuf, "F%s$", moduleName); /* scope is file */ + else + dbuf_printf(oBuf, "G$"); /* scope is global */ + } else { + /* symbol is local */ + dbuf_printf(oBuf, "L%s$", (sym->localof ? sym->localof->name : "-null-")); + } + dbuf_printf(oBuf, "%s$%d$%d", sym->name, sym->level, sym->block); +} + + +/*-----------------------------------------------------------------*/ +/* pblaze_printChar - formats and prints a characater string with DB */ +/*-----------------------------------------------------------------*/ +void pblaze_printChar(struct dbuf_s *oBuf, char *s, int plen) +{ + int i; + int len = plen; + int pplen = 0; + char buf[100]; + char *p = buf; + + while (len && pplen < plen) { + i = 60; + while (i && pplen < plen) { + if (*s < ' ' || *s == '\"' || *s == '\\') { + *p = '\0'; + if (p != buf) + dbuf_tprintf(oBuf, "\t!ascii\n", buf); + dbuf_tprintf(oBuf, "\t!db !constbyte\n", (unsigned char) *s); + p = buf; + } else { + *p = *s; + p++; + } + s++; + pplen++; + i--; + } + if (p != buf) { + *p = '\0'; + dbuf_tprintf(oBuf, "\t!ascii\n", buf); + p = buf; + } + + if (len > 60) + len -= 60; + else + len = 0; + } + while (pplen < plen) { + dbuf_tprintf(oBuf, "\t!db !constbyte\n", 0); + pplen++; + } +} + +/*-----------------------------------------------------------------*/ +/* pblaze_emitRegularMap - emit code for maps with no special cases */ +/*-----------------------------------------------------------------*/ +static void pblaze_emitRegularMap(memmap * map, bool addPublics, bool arFlag) +{ + symbol *sym; + ast *ival = NULL; + + if (!map) + return; + + if (addPublics) { + + if (map->regsp) + dbuf_tprintf(&map->oBuf, "\t!org\n", 0); + } + + for (sym = setFirstItem(map->syms); sym; sym = setNextItem(map->syms)) { + symbol *newSym = NULL; + + /* if extern then add it into the extern list */ + if (IS_EXTERN(sym->etype)) { + addSetHead(&pblaze_externs, sym); + continue; + } + + /* if allocation required check is needed + then check if the symbol really requires + allocation only for local variables */ + + if (arFlag && !IS_AGGREGATE(sym->type) && !(sym->_isparm && !IS_REGPARM(sym->etype)) && !sym->allocreq && sym->level) + continue; + + /* for bitvar locals and parameters */ + if (!arFlag && !sym->allocreq && sym->level && !SPEC_ABSA(sym->etype)) { + continue; + } + + /* if global variable & not static or extern + and addPublics allowed then add it to the public set */ + if ((sym->level == 0 || + (sym->_isparm && !IS_REGPARM(sym->etype))) && + addPublics && !IS_STATIC(sym->etype) && (IS_FUNC(sym->type) ? (sym->used || IFFUNC_HASBODY(sym->type)) : 1)) { + addSetHead(&pblaze_publics, sym); + } + + /* if extern then do nothing or is a function + then do nothing */ + if (IS_FUNC(sym->type) && !(sym->isitmp)) + continue; + + /* if it has an initial value then do it only if + it is a global variable */ + if (sym->ival && sym->level == 0) { + if ((SPEC_OCLS(sym->etype) == xidata) && !SPEC_ABSA(sym->etype)) { + sym_link *t; + /* create a new "XINIT (CODE)" symbol, that will be emited later + in the static seg */ + newSym = copySymbol(sym); + SPEC_OCLS(newSym->etype) = xinit; + SNPRINTF(newSym->name, sizeof(newSym->name), "__xinit_%s", sym->name); + SNPRINTF(newSym->rname, sizeof(newSym->rname), "__xinit_%s", sym->rname); + /* find the first non-array link */ + t = newSym->type; + while (IS_ARRAY(t)) + t = t->next; + if (IS_SPEC(t)) + SPEC_CONST(t) = 1; + else + DCL_PTR_CONST(t) = 1; + SPEC_STAT(newSym->etype) = 1; + resolveIvalSym(newSym->ival, newSym->type); + + // add it to the "XINIT (CODE)" segment + addSet(&xinit->syms, newSym); + + if (!SPEC_ABSA(sym->etype)) { + struct dbuf_s tmpBuf; + + dbuf_init(&tmpBuf, 4096); + // before allocation we must parse the sym->ival tree + // but without actually generating initialization code + ++noAlloc; + resolveIvalSym(sym->ival, sym->type); + ++pblaze_noInit; + printIval(sym, sym->type, sym->ival, &tmpBuf, TRUE); + --pblaze_noInit; + --noAlloc; + dbuf_destroy(&tmpBuf); + } + } else { + if (IS_AGGREGATE(sym->type)) { + ival = initAggregates(sym, sym->ival, NULL); + } else { + if (getNelements(sym->type, sym->ival) > 1) { + werrorfl(sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar", sym->name); + } + ival = newNode('=', newAst_VALUE(symbolVal(sym)), decorateType(resolveSymbols(list2expr(sym->ival)), RESULT_TYPE_NONE)); + } + codeOutBuf = &statsg->oBuf; + + if (ival) { + // set ival's lineno to where the symbol was defined + setAstFileLine(ival, filename = sym->fileDef, lineno = sym->lineDef); + // check if this is not a constant expression + if (!constExprTree(ival)) { + werror(E_CONST_EXPECTED, "found expression"); + // but try to do it anyway + } + pblaze_allocInfo = 0; + if (!astErrors(ival)) + eBBlockFromiCode(iCodeFromAst(ival)); + pblaze_allocInfo = 1; + } + } + } + + /* if it has an absolute address then generate + an equate for this no need to allocate space */ + if (SPEC_ABSA(sym->etype) && !sym->ival) { + char *equ = "="; + + /* print extra debug info if required */ + if (options.debug) { + pblaze_emitDebugSym(&map->oBuf, sym); + dbuf_printf(&map->oBuf, " == 0x%04x\n", SPEC_ADDR(sym->etype)); + } + if (TARGET_IS_XA51) { + if (map == sfr) { + equ = "sfr"; + } else if (map == bit || map == sfrbit) { + equ = "bit"; + } + } + dbuf_printf(&map->oBuf, "%s\t%s\t0x%04x\n", sym->rname, equ, SPEC_ADDR(sym->etype)); + } else { + int size = getSize(sym->type) + sym->flexArrayLength; + if (size == 0) { + werrorfl(sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE, sym->name); + } + /* allocate space */ + if (SPEC_ABSA(sym->etype)) { + dbuf_tprintf(&map->oBuf, "\t!org\n", SPEC_ADDR(sym->etype)); + } + /* print extra debug info if required */ + if (options.debug) { + pblaze_emitDebugSym(&map->oBuf, sym); + dbuf_printf(&map->oBuf, "==.\n"); + } + if (IS_STATIC(sym->etype) || sym->level) + dbuf_tprintf(&map->oBuf, "!slabeldef\n", sym->rname); + else + dbuf_tprintf(&map->oBuf, "!labeldef\n", sym->rname); + dbuf_tprintf(&map->oBuf, "\t!ds\n", (unsigned int) size & 0xffff); + } + sym->ival = NULL; + } +} + + +/*-----------------------------------------------------------------*/ +/* pblaze_emitStaticSeg - emitcode for the static segment */ +/*-----------------------------------------------------------------*/ +void pblaze_emitStaticSeg(memmap * map, struct dbuf_s *oBuf) +{ + symbol *sym; + + /* fprintf(out, "\t.area\t%s\n", map->sname); */ + + /* for all variables in this segment do */ + for (sym = setFirstItem(map->syms); sym; sym = setNextItem(map->syms)) { + /* if it is "extern" then do nothing */ + if (IS_EXTERN(sym->etype)) + continue; + + /* if it is not static add it to the public table */ + if (!IS_STATIC(sym->etype)) { + addSetHead(&pblaze_publics, sym); + } + + /* if it has an absolute address and no initializer */ + if (SPEC_ABSA(sym->etype) && !sym->ival) { + if (options.debug) { + pblaze_emitDebugSym(oBuf, sym); + dbuf_printf(oBuf, " == 0x%04x\n", SPEC_ADDR(sym->etype)); + } + dbuf_printf(oBuf, "%s\t=\t0x%04x\n", sym->rname, SPEC_ADDR(sym->etype)); + } else { + int size = getSize(sym->type); + + if (size == 0) { + werrorfl(sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE, sym->name); + } + /* if it has an initial value */ + if (sym->ival) { + if (SPEC_ABSA(sym->etype)) { + dbuf_tprintf(oBuf, "\t!org\n", SPEC_ADDR(sym->etype)); + } + if (options.debug) { + pblaze_emitDebugSym(oBuf, sym); + dbuf_printf(oBuf, " == .\n"); + } + dbuf_printf(oBuf, "%s:\n", sym->rname); + ++noAlloc; + resolveIvalSym(sym->ival, sym->type); + printIval(sym, sym->type, sym->ival, oBuf, map != xinit); + --noAlloc; + /* if sym is a simple string and sym->ival is a string, + WE don't need it anymore */ + if (IS_ARRAY(sym->type) && IS_CHAR(sym->type->next) && + IS_AST_SYM_VALUE(list2expr(sym->ival)) && list2val(sym->ival)->sym->isstrlit) { + freeStringSymbol(list2val(sym->ival)->sym); + } + } else { + /* allocate space */ + if (options.debug) { + pblaze_emitDebugSym(oBuf, sym); + dbuf_printf(oBuf, " == .\n"); + } + dbuf_printf(oBuf, "%s:\n", sym->rname); + /* special case for character strings */ + if (IS_ARRAY(sym->type) && IS_CHAR(sym->type->next) && SPEC_CVAL(sym->etype).v_char) { + pblaze_printChar(oBuf, SPEC_CVAL(sym->etype).v_char, size); + } else { + dbuf_tprintf(oBuf, "\t!ds\n", (unsigned int) size & 0xffff); + } + } + } + } +} + +/*-----------------------------------------------------------------*/ +/* pblaze_emitMaps - emits the code for the data portion the code */ +/*-----------------------------------------------------------------*/ +void pblaze_emitMaps(void) +{ + int publicsfr = TARGET_IS_MCS51; /* Ideally, this should be true for all */ + /* ports but let's be conservative - EEP */ + + inInitMode++; + /* no special considerations for the following + data, idata & bit & xdata */ + pblaze_emitRegularMap(data, TRUE, TRUE); + pblaze_emitRegularMap(idata, TRUE, TRUE); + pblaze_emitRegularMap(d_abs, TRUE, TRUE); + pblaze_emitRegularMap(i_abs, TRUE, TRUE); + pblaze_emitRegularMap(bit, TRUE, TRUE); + pblaze_emitRegularMap(pdata, TRUE, TRUE); + pblaze_emitRegularMap(xdata, TRUE, TRUE); + pblaze_emitRegularMap(x_abs, TRUE, TRUE); + if (port->genXINIT) { + pblaze_emitRegularMap(xidata, TRUE, TRUE); + } + pblaze_emitRegularMap(sfr, publicsfr, FALSE); + pblaze_emitRegularMap(sfrbit, publicsfr, FALSE); + pblaze_emitRegularMap(home, TRUE, FALSE); + pblaze_emitRegularMap(code, TRUE, FALSE); + + + pblaze_emitStaticSeg(c_abs, &code->oBuf); + inInitMode--; +} + +/*-----------------------------------------------------------------*/ +/* pblaze_createInterruptVect - creates the interrupt vector */ +/*-----------------------------------------------------------------*/ +void pblaze_createInterruptVect(struct dbuf_s *vBuf) +{ + pblaze_mainf = newSymbol("main", 0); + pblaze_mainf->block = 0; + + /* only if the main function exists */ + if (!(pblaze_mainf = findSymWithLevel(SymbolTab, pblaze_mainf))) { + if (!options.cc_only && !noAssemble && !options.c1mode) + werror(E_NO_MAIN); + return; + } + + /* if the main is only a prototype ie. no body then do nothing */ + if (!IFFUNC_HASBODY(pblaze_mainf->type)) { + /* if ! compile only then main function should be present */ + if (!options.cc_only && !noAssemble) + werror(E_NO_MAIN); + return; + } + //dbuf_printf (vBuf, "__interrupt_vect:\n"); + + if (!port->genIVT || !(port->genIVT(vBuf, interrupts, maxInterrupts))) { + /* There's no such thing as a "generic" interrupt table header. */ + wassert(0); + } +} + +char *pblaze_iComments1 = { + ";--------------------------------------------------------\n" "; File Created by SDCC : free open source ANSI-C Compiler\n" +}; + +char *pblaze_iComments2 = { + ";--------------------------------------------------------\n" +}; + + +/*-----------------------------------------------------------------*/ +/* pbInitialComments - puts in some initial comments */ +/*-----------------------------------------------------------------*/ +void pbInitialComments(FILE * afile) +{ + time_t t; + time(&t); + fprintf(afile, "%s", pblaze_iComments1); + fprintf(afile, "; Version " SDCC_VERSION_STR " #%s (%s) (%s)\n", getBuildNumber(), getBuildDate(), getBuildEnvironment()); + fprintf(afile, "; This file was generated %s", asctime(localtime(&t))); + fprintf(afile, "%s", pblaze_iComments2); +} + + +/*-----------------------------------------------------------------*/ +/* pblaze_printPublics - generates .global for publics */ +/*-----------------------------------------------------------------*/ +void pblaze_printPublics(FILE * afile) +{ + symbol *sym; + + fprintf(afile, "%s", pblaze_iComments2); + fprintf(afile, "; Public variables in this module\n"); + fprintf(afile, "%s", pblaze_iComments2); + + for (sym = setFirstItem(pblaze_publics); sym; sym = setNextItem(pblaze_publics)) + tfprintf(afile, "\t!global\n", sym->rname); +} + + +/*-----------------------------------------------------------------*/ +/* pblaze_printExterns - generates .global for Externs */ +/*-----------------------------------------------------------------*/ +void pblaze_printExterns(FILE * afile) +{ + fprintf(afile, "%s", pblaze_iComments2); + fprintf(afile, "; Externals used\n"); + fprintf(afile, "%s", pblaze_iComments2); + +} + +/*-----------------------------------------------------------------*/ +/* pblaze_emitOverlay - will emit code for the overlay stuff */ +/*-----------------------------------------------------------------*/ +static void pblaze_emitOverlay(struct dbuf_s *aBuf) +{ + set *ovrset; + + + /* for each of the sets in the overlay segment do */ + for (ovrset = setFirstItem(ovrSetSets); ovrset; ovrset = setNextItem(ovrSetSets)) { + symbol *sym; + + for (sym = setFirstItem(ovrset); sym; sym = setNextItem(ovrset)) { + /* if extern then it is in the pblaze_publics table: do nothing */ + if (IS_EXTERN(sym->etype)) + continue; + + /* if allocation required check is needed + then check if the symbol really requires + allocation only for local variables */ + if (!IS_AGGREGATE(sym->type) && !(sym->_isparm && !IS_REGPARM(sym->etype)) + && !sym->allocreq && sym->level) + continue; + + /* if global variable & not static or extern + and addPublics allowed then add it to the public set */ + if ((sym->_isparm && !IS_REGPARM(sym->etype)) + && !IS_STATIC(sym->etype)) { + addSetHead(&pblaze_publics, sym); + } + + /* if extern then do nothing or is a function + then do nothing */ + if (IS_FUNC(sym->type)) + continue; + + /* print extra debug info if required */ + if (options.debug) { + if (!sym->level) { /* global */ + if (IS_STATIC(sym->etype)) + dbuf_printf(aBuf, "F%s$", moduleName); /* scope is file */ + else + dbuf_printf(aBuf, "G$"); /* scope is global */ + } else + /* symbol is local */ + dbuf_printf(aBuf, "L%s$", (sym->localof ? sym->localof->name : "-null-")); + dbuf_printf(aBuf, "%s$%d$%d", sym->name, sym->level, sym->block); + } + + /* if is has an absolute address then generate + an equate for this no need to allocate space */ + if (SPEC_ABSA(sym->etype)) { + if (options.debug) + dbuf_printf(aBuf, " == 0x%04x\n", SPEC_ADDR(sym->etype)); + + dbuf_printf(aBuf, "%s\t=\t0x%04x\n", sym->rname, SPEC_ADDR(sym->etype)); + } else { + int size = getSize(sym->type); + + if (size == 0) { + werrorfl(sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE); + } + if (options.debug) + dbuf_printf(aBuf, "==.\n"); + + /* allocate space */ + dbuf_tprintf(aBuf, "!labeldef\n", sym->rname); + dbuf_tprintf(aBuf, "\t!ds\n", (unsigned int) getSize(sym->type) & 0xffff); + } + } + } +} + +/*-----------------------------------------------------------------*/ +/* glue - the final glue that hold the whole thing together */ +/*-----------------------------------------------------------------*/ +void pblaze_glue(void) +{ + struct dbuf_s vBuf; + struct dbuf_s ovrBuf; + struct dbuf_s asmFileName; + FILE *asmFile; + + + pblaze_genCodeLoop(); + + dbuf_init(&vBuf, 4096); + dbuf_init(&ovrBuf, 4096); + + /* print the global struct definitions */ + if (options.debug) + cdbStructBlock(0); + + /* PENDING: this isn't the best place but it will do */ + if (port->general.glue_up_main) { + /* create the interrupt vector table */ + pblaze_createInterruptVect(&vBuf); + } + + /* emit code for the all the variables declared */ + pblaze_emitMaps(); + /* do the overlay segments */ + pblaze_emitOverlay(&ovrBuf); + + outputDebugSymbols(); + + /* now put it all together into the assembler file */ + /* create the assembler file name */ + + /* -o option overrides default name? */ + dbuf_init(&asmFileName, PATH_MAX); + if ((noAssemble || options.c1mode) && fullDstFileName) { + dbuf_append_str(&asmFileName, fullDstFileName); + } else { + dbuf_append_str(&asmFileName, dstFileName); + dbuf_append_str(&asmFileName, port->assembler.file_ext); + } + + if (!(asmFile = fopen(dbuf_c_str(&asmFileName), "w"))) { + werror(E_FILE_OPEN_ERR, dbuf_c_str(&asmFileName)); + dbuf_destroy(&asmFileName); + exit(EXIT_FAILURE); + } + dbuf_destroy(&asmFileName); + + /* initial comments */ + pbInitialComments(asmFile); + + + /* Let the port generate any global directives, etc. */ + if (port->genAssemblerPreamble) { + port->genAssemblerPreamble(asmFile); + } + + /* print the global variables in this module */ + //pblaze_printPublics (asmFile); + if (port->assembler.externGlobal) + pblaze_printExterns(asmFile); + + + /* If the port wants to generate any extra areas, let it do so. */ + if (port->extraAreas.genExtraAreaDeclaration) { + port->extraAreas.genExtraAreaDeclaration(asmFile, pblaze_mainf && IFFUNC_HASBODY(pblaze_mainf->type)); + } + + /* copy global & static initialisations */ + fprintf(asmFile, "%s", pblaze_iComments2); + fprintf(asmFile, "; global & static initialisations\n"); + fprintf(asmFile, "%s", pblaze_iComments2); + + if (pblaze_mainf && IFFUNC_HASBODY(pblaze_mainf->type)) { + if (port->genInitStartup) { + port->genInitStartup(asmFile); + } else { + + // if the port can copy the XINIT segment to XISEG + if (port->genXINIT) { + port->genXINIT(asmFile); + } + } + } + dbuf_write_and_destroy(&statsg->oBuf, asmFile); + + if (port->general.glue_up_main && pblaze_mainf && IFFUNC_HASBODY(pblaze_mainf->type)) { + /* This code is generated in the post-static area. + * This area is guaranteed to follow the static area + * by the ugly shucking and jiving about 20 lines ago. + */ + + fprintf(asmFile, "\tLOAD\tsF, %s%02x\n", pblaze_options.dialect ? "" : "$", MEMSIZE - 1); + fprintf(asmFile, "\tJUMP\t__sdcc_program_startup\n"); + } + + fprintf(asmFile, "%s" "; Home\n" "%s", pblaze_iComments2, pblaze_iComments2); + dbuf_write_and_destroy(&home->oBuf, asmFile); + + if (pblaze_mainf && IFFUNC_HASBODY(pblaze_mainf->type)) { + /* entry point @ start of HOME */ + fprintf(asmFile, "__sdcc_program_startup:\n"); + + /* put in jump or call to main */ + if (options.mainreturn) { + fprintf(asmFile, "\tJUMP\t_main\n"); /* needed? */ + if (!options.noCcodeInAsm) + fprintf(asmFile, ";\treturn from main will return to caller\n"); + } else { + fprintf(asmFile, "\tCALL\t_main\n"); + if (!options.noCcodeInAsm) + fprintf(asmFile, ";\treturn from main will lock up\n"); + fprintf(asmFile, "__sdcc_loop:\n"); + fprintf(asmFile, "\tJUMP\t__sdcc_loop\n"); + } + } + /* copy over code */ + fprintf(asmFile, "%s", pblaze_iComments2); + fprintf(asmFile, "; code\n"); + fprintf(asmFile, "%s", pblaze_iComments2); + dbuf_write_and_destroy(&code->oBuf, asmFile); + + if (port->genAssemblerEnd) { + port->genAssemblerEnd(asmFile); + } + + /* copy the interrupt vector table */ + if (pblaze_mainf && IFFUNC_HASBODY(pblaze_mainf->type)) { + fprintf(asmFile, "%s", pblaze_iComments2); + fprintf(asmFile, "; interrupt vector \n"); + fprintf(asmFile, "%s", pblaze_iComments2); + dbuf_write_and_destroy(&vBuf, asmFile); + } + + fclose(asmFile); +} diff -NaurbB sdcc-src-3.1.0/src/pblaze/pbglue.h sdcc-src-3.1.0-pblaze/src/pblaze/pbglue.h --- sdcc-src-3.1.0/src/pblaze/pbglue.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/pblaze/pbglue.h 2011-08-23 15:56:30.000000000 +0200 @@ -0,0 +1,43 @@ +/*------------------------------------------------------------------------- + pbglue.h - glues everything we have done together into one file. + + Written By: + Sandeep Dutta . sandeep.dutta@usa.net (1998) + && + Jakub Hornik, xhorni00<at>stud.fit.vutbr.cz + Master Thesis Project: + Compiler Back-End of Subset of Language C for 8-Bit Processor + Date: + 2011 + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ +#include "common.h" + +#ifndef PBGLUE_H +#define PBGLUE_H 1 + +void pblaze_glue(void); + +extern symbol *interrupts[]; +extern set *pblaze_publics; + + + +#endif diff -NaurbB sdcc-src-3.1.0/src/pblaze/peeph.def sdcc-src-3.1.0-pblaze/src/pblaze/peeph.def --- sdcc-src-3.1.0/src/pblaze/peeph.def 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/pblaze/peeph.def 2011-08-23 15:56:30.000000000 +0200 @@ -0,0 +1,17 @@ + +replace { + FETCH %1, %2 + LOAD %1, %3 +} by { + ; Peephole 1 unnecessary fetch %1, %2 + LOAD %1, %3 +} + +// should be one of the last peepholes +replace{ +%1: +} by { + ; Peephole 500 removed redundant label %1 +} if labelRefCount(%1 0) + + diff -NaurbB sdcc-src-3.1.0/src/pblaze/ralloc.c sdcc-src-3.1.0-pblaze/src/pblaze/ralloc.c --- sdcc-src-3.1.0/src/pblaze/ralloc.c 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/pblaze/ralloc.c 2011-12-05 23:46:59.162175900 +0100 @@ -0,0 +1,1827 @@ +/*------------------------------------------------------------------------ +ralloc.c - source file for register allocation. (XILINX PICOBLAZE) specific + +Author: + Jakub Hornik, xhorni00<at>stud.fit.vutbr.cz +Master Thesis Project: + Compiler Back-End of Subset of Language C for 8-Bit Processor +Date: + 2011 + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +In other words, you are welcome to use, share and improve this program. +You are forbidden to forbid anyone else to use, share and improve +what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ + +#include "common.h" +#include "ralloc.h" +#include "gen.h" + +//#define SYMBOL_IN_REG(reg) validateOpType(reg->currOper, "OP_SYMBOL", #op, SYMBOL, __FILE__, __LINE__)->operand.symOperand +#define SYMBOL_IN_REG(reg) OP_SYMBOL(reg.currOper) +#define RCV ic->op == RECEIVE +#define GLOBORVOLATIL(x) (IS_OP_GLOBAL(x) || IS_OP_VOLATILE(x)) +#define IS_ENDLABEL(x) x->op == LABEL && strstr( IC_LABEL(x)->name, "_ifend_") + +#define SKIP_IC5(x) (x->op == CALL || \ + x->op == RETURN || \ + x->op == ENDFUNCTION || \ + x->op == FUNCTION || \ + x->op == SEND || \ + x->op == RECEIVE ) + + +#define SKIP_NO_OP(x) (x->op == GOTO || \ + x->op == LABEL || \ + x->op == FUNCTION || \ + x->op == INLINEASM || \ + x->op == JUMPTABLE || \ + x->op == IFX || \ + x->op == CALL || \ + x->op == PCALL || \ + x->op == ARRAYINIT || \ + x->op == CRITICAL || \ + x->op == ENDCRITICAL || \ + x->op == ENDFUNCTION ) + +extern void genPBLAZECode(iCode *); +extern unsigned fPBLAZEReturnSize; +extern void emitStore(char *r, int mem); +extern void emitFetch(char *r, int mem); + +/* Global data */ +static struct { + bitVect *regAssigned; + bitVect *funcrUsed; /* registers used in a function */ + int stackExtend; + int dataExtend; +} _G; + +/* Shared with gen.c */ +int pblaze_ptrRegReq; /* pointer register required */ + +int gInit = 0; + +/* PBLAZE registers */ +reg_info regsPBLAZE[] = { + {REG_GPR, S0_IDX, "s0", NULL, 0, 0, SAME_VAL, 1, 0}, + {REG_GPR, S1_IDX, "s1", NULL, 0, 0, SAME_VAL, 1, 0}, + {REG_GPR, S2_IDX, "s2", NULL, 0, 0, SAME_VAL, 1, 0}, + {REG_GPR, S3_IDX, "s3", NULL, 0, 0, SAME_VAL, 1, 0}, + {REG_GPR, S4_IDX, "s4", NULL, 0, 0, SAME_VAL, 1, 0}, + {REG_GPR, S5_IDX, "s5", NULL, 0, 0, SAME_VAL, 1, 0}, + {REG_GPR, S6_IDX, "s6", NULL, 0, 0, SAME_VAL, 1, 0}, + {REG_GPR, S7_IDX, "s7", NULL, 0, 0, SAME_VAL, 1, 0}, + {REG_GPR, S8_IDX, "s8", NULL, 0, 0, SAME_VAL, 1, 0}, + {REG_GPR, S9_IDX, "s9", NULL, 0, 0, SAME_VAL, 1, 0}, + {REG_GPR, SA_IDX, "sA", NULL, 0, 0, SAME_VAL, 1, 0}, + {REG_GPR, SB_IDX, "sB", NULL, 0, 0, SAME_VAL, 1, 1}, + {REG_GPR, SC_IDX, "sC", NULL, 0, 0, SAME_VAL, 1, 1}, + {REG_GPR, SD_IDX, "sD", NULL, 0, 0, SAME_VAL, 1, 1}, + {REG_GPR, SE_IDX, "sE", NULL, 0, 0, SAME_VAL, 1, 1}, + {REG_GPR, SF_IDX, "sF", NULL, 0, 0, SAME_VAL, 0, 1}, +}; + + + +int pblaze_nRegs = PBLAZENREGS - SEND_REG_COUNT - 1; // avaiable regs +int pblaze_totalRegs = PBLAZENREGS; // total regs +int pblaze_fReg = 0; /* first allocatable register */ + +// temp regs counter +int ctr = 0; + +memMap memPBLAZE[MEMSIZE]; + + +void printRegs(void) +{ + + int i; + + printf("==============PicoBlaze=Registers=============\n"); + + for (i = 0; i < pblaze_nRegs; i++) { + if (regsPBLAZE[i].isFree == 0 && regsPBLAZE[i].currOper) { + printf("%s ->\t %s:%d\n", regsPBLAZE[i].name, SYMBOL_IN_REG(regsPBLAZE[i])->name, regsPBLAZE[i].offset); + + } else if (regsPBLAZE[i].isReserved == 1 && regsPBLAZE[i].currOper) + //printf("%s ->\t %s\n", regsPBLAZE[i].name, "reserved"); + printf("%sR ->\t %s:%d\n", regsPBLAZE[i].name, SYMBOL_IN_REG(regsPBLAZE[i])->name, regsPBLAZE[i].offset); + } + printf("==============================================\n\n"); +} + + +void printMemory(void) +{ + + int i; + + printf("==============PicoBlaze=Memory================\n"); + + for (i = 0; i < MEMSIZE; i++) { + if (memPBLAZE[i].isFree == 0 && memPBLAZE[i].currOper) { + printf("%d ->\t %s:%d\n", memPBLAZE[i].addr, SYMBOL_IN_REG(memPBLAZE[i])->name, memPBLAZE[i].offset); + + } + } + printf("==============================================\n\n"); +} + +/*-----------------------------------------------------------------*/ +/* Prints constants name depending on the selected dialect */ +/*-----------------------------------------------------------------*/ +void printConstants(FILE * of) +{ + int i; + for (i = 0; i < MEMSIZE; i++) { + if (memPBLAZE[i].isFree == 0 && memPBLAZE[i].currOper && IS_OP_GLOBAL(memPBLAZE[i].currOper)) { + if (pblaze_options.dialect && getSize(operandType(memPBLAZE[i].currOper)) == 1) + fprintf(of, "\tCONSTANT\t%s, %02x\n", SYMBOL_IN_REG(memPBLAZE[i])->rname, i); + else if (pblaze_options.dialect) + fprintf(of, "\tCONSTANT\t%s_%d, %02x\n", SYMBOL_IN_REG(memPBLAZE[i])->rname, memPBLAZE[i].offset, i); + else if (getSize(operandType(memPBLAZE[i].currOper)) == 1) + fprintf(of, "\t%s\tEQU $%02x\n", SYMBOL_IN_REG(memPBLAZE[i])->rname, i); + else + fprintf(of, "\t%s_%d\tEQU $%02x\n", SYMBOL_IN_REG(memPBLAZE[i])->rname, memPBLAZE[i].offset, i); + } + } + fprintf(of, "\n"); +} + +/*-----------------------------------------------------------------*/ +/* operName - returns a memory name or a memory adress */ +/*-----------------------------------------------------------------*/ +char *operName(int addr) +{ + char *s = buffer; + if (memPBLAZE[addr].isFree || !IS_OP_GLOBAL(memPBLAZE[addr].currOper)) + sprintf(s, "%s%02x", pblaze_options.dialect ? "" : "$", addr); + else if (getSize(operandType(memPBLAZE[addr].currOper)) == 1) + sprintf(s, "%s", SYMBOL_IN_REG(memPBLAZE[addr])->rname); + else + sprintf(s, "%s_%d", SYMBOL_IN_REG(memPBLAZE[addr])->rname, memPBLAZE[addr].offset); + return Safe_strdup(s); +} + +/*-----------------------------------------------------------------*/ +/* pblaze_regWithIdx - returns pointer to register with index number*/ +/*-----------------------------------------------------------------*/ +reg_info *pblaze_regWithIdx(int idx) +{ + int i; + + for (i = 0; i < pblaze_totalRegs; i++) + if (regsPBLAZE[i].rIdx == idx) + return ®sPBLAZE[i]; + + werror(E_INTERNAL_ERROR, __FILE__, __LINE__, "regWithIdx not found"); + exit(1); +} + +/*-----------------------------------------------------------------*/ +/* check for memory collisions (between data part and the stack */ +/*-----------------------------------------------------------------*/ +void staticMemoryCheck(int t) +{ + static int top = MEMSIZE - 1; + if (t >= 0 && t < MEMSIZE) + top = t; + + if (!memPBLAZE[top].isFree || memPBLAZE[top].currOper) { + fprintf(stderr, "pblaze port error: not enough memory\n"); + exit(0); + } + +} + +/*-----------------------------------------------------------------*/ +/* Init stack */ +/*-----------------------------------------------------------------*/ +void initPBLAZEStack(void) +{ + // top of the stack pointer + reg_info *rStack; + //pblaze_nRegs = 15; + rStack = pblaze_regWithIdx(SF_IDX); + rStack->currOper = NULL; + rStack->isFree = 0; + rStack->isReserved = 1; + +} + +/*-----------------------------------------------------------------*/ +/* firstFreeReg - returns first free register */ +/*-----------------------------------------------------------------*/ +static reg_info *firstFreeReg(void) +{ + int i; + + for (i = 0; i < pblaze_nRegs; i++) { + if (regsPBLAZE[i].isFree == 1 && regsPBLAZE[i].isReserved == 0) + return ®sPBLAZE[i]; + } + + return NULL; +} + +/*-----------------------------------------------------------------*/ +/* firstFreeMem - returns first free register */ +/*-----------------------------------------------------------------*/ +memMap *firstFreeMem(void) +{ + int i; + + for (i = 0; i < MEMSIZE; i++) { + if (memPBLAZE[i].isFree == 1) + return &memPBLAZE[i]; + } + + return NULL; +} + +/*-----------------------------------------------------------------*/ +/* isOpInReg - test if operand is in registers */ +/*-----------------------------------------------------------------*/ +int isOpInReg(operand * op) +{ + int i, found = 0; + + if (!op) + return 0; + + for (i = pblaze_fReg; i < pblaze_nRegs; i++) { + if (regsPBLAZE[i].currOper && pblaze_operandsEqu(op, regsPBLAZE[i].currOper)) { + found++; + } + } + + return found; +} + + +/*-----------------------------------------------------------------*/ +/* isOffsetInReg - test if operand's offset is in registers */ +/*-----------------------------------------------------------------*/ +reg_info *isOffsetInReg(operand * op, int offset) +{ + int i; + + if (!op) + return NULL; + + for (i = pblaze_fReg; i < pblaze_nRegs; i++) { + if (regsPBLAZE[i].currOper && pblaze_operandsEqu(op, regsPBLAZE[i].currOper) && regsPBLAZE[i].offset == offset) { + return ®sPBLAZE[i]; + } + } + + return NULL; +} + +/*-----------------------------------------------------------------*/ +/* isOffsetInMem - test if operand's offset is in the memory */ +/* returns pointer into memory */ +/*-----------------------------------------------------------------*/ +memMap *isOffsetInMem(operand * op, int offset) +{ + int i; + if (op == NULL || op->type != SYMBOL) + return NULL; + + if (!op) + return NULL; + + for (i = 0; i < MEMSIZE; i++) { + if (memPBLAZE[i].currOper && pblaze_operandsEqu(op, memPBLAZE[i].currOper)) { + if (memPBLAZE[i].offset == offset) + return &memPBLAZE[i]; + } + } + + return NULL; +} + +/*-----------------------------------------------------------------*/ +/* isOpInMem - test if symbol is in the memory */ +/* returns pointer into memory */ +/*-----------------------------------------------------------------*/ +memMap *isOpInMem(operand * op) +{ + int i, size, found = 0; + memMap *m = NULL; + if (op == NULL || op->type != SYMBOL) + return NULL; + + symbol *s = OP_SYMBOL(op); + + if (!op) + return NULL; + + size = getSize(s->type); + + for (i = 0; i < MEMSIZE; i++) { + if (memPBLAZE[i].currOper && pblaze_operandsEqu(op, memPBLAZE[i].currOper)) { + found++; + if (m == NULL) + m = &memPBLAZE[i]; + } + } + + if (found == size) + return m; + return NULL; + +} + +/*-----------------------------------------------------------------*/ +/* lockReg - set a register as reserved */ +/*-----------------------------------------------------------------*/ +void lockReg(reg_info * r) +{ + r->isReserved = 1; +} + +/*-----------------------------------------------------------------*/ +/* unlockReg - unset a register as reserved */ +/*-----------------------------------------------------------------*/ +void unlockReg(reg_info * r) +{ + if (r->rIdx < pblaze_nRegs) + r->isReserved = 0; +} + +/*-----------------------------------------------------------------*/ +/* freeReg - frees a register */ +/*-----------------------------------------------------------------*/ +static void freeReg(reg_info * reg) +{ + if (reg) { + reg->isFree = 1; + reg->currOper = NULL; + reg->offset = 0; + reg->ptrOffset = 0; + reg->isReserved = 0; + reg->changed = SAME_VAL; + } +} + +/*-----------------------------------------------------------------*/ +/* freeMem - frees a memory cell */ +/*-----------------------------------------------------------------*/ +static void freeMem(memMap * mem) +{ + if (mem) { + mem->currOper = NULL; + mem->offset = 0; + mem->ptrOffset = 0; + mem->nextPart = -1; + mem->reserved = 0; + mem->isGlobal = 0; + mem->isFree = 1; + mem->isOnlyInMem = 0; + } +} + +/*-----------------------------------------------------------------*/ +/* initPBLAZEMem - init PicoBlaze memory */ +/*-----------------------------------------------------------------*/ +void initPBLAZEMem(void) +{ + int i; + for (i = 0; i < MEMSIZE; i++) { + + memPBLAZE[i].addr = i; + memPBLAZE[i].currOper = NULL; + memPBLAZE[i].offset = 0; + memPBLAZE[i].ptrOffset = 0; + memPBLAZE[i].nextPart = -1; + memPBLAZE[i].reserved = 0; + memPBLAZE[i].isGlobal = 0; + memPBLAZE[i].isFree = 1; + memPBLAZE[i].isOnlyInMem = 0; + + } +} + +/*-----------------------------------------------------------------*/ +/* freeOpFromReg - frees an operand from registers */ +/*-----------------------------------------------------------------*/ +void freeOpFromReg(operand * op) +{ + int i, size; + symbol *s; + reg_info *rtmp; + + if (!op) + return; + + s = OP_SYMBOL(op); + size = getSize(operandType(op)); + + for (i = 0; i < size; i++) { + if (s->regs[i]) { + rtmp = s->regs[i]; + s->regs[i] = NULL; + freeReg(rtmp); + } + } + s->nRegs = 0; +} + +/*-----------------------------------------------------------------*/ +/* freeOffsetFromReg - frees an operand offset from registers */ +/*-----------------------------------------------------------------*/ +void freeOffsetFromReg(operand * op, int offset) +{ + if (!op) + return; + + symbol *s = OP_SYMBOL(op); + reg_info *rtmp; + + if (s->regs[offset]) { + rtmp = s->regs[offset]; + s->regs[offset] = NULL; + freeReg(rtmp); + } +} + +/*-----------------------------------------------------------------*/ +/* freeOpFromMem - frees an operand from the memory */ +/*-----------------------------------------------------------------*/ +void freeOpFromMem(operand * op) +{ + int i; + + if (!op) + return; + + for (i = 0; i < MEMSIZE; i++) { + if (memPBLAZE[i].currOper == op) { + freeMem(&memPBLAZE[i]); + } + } +} + +/*-----------------------------------------------------------------*/ +/* freeOffsetFromMem - frees an operand offset from the memory */ +/*-----------------------------------------------------------------*/ +void freeOffsetFromMem(operand * op, int offset) +{ + int i; + + if (!op) + return; + + for (i = 0; i < MEMSIZE; i++) { + if (memPBLAZE[i].currOper && pblaze_operandsEqu(op, memPBLAZE[i].currOper) && memPBLAZE[i].offset == offset) { + freeMem(&memPBLAZE[i]); + } + } +} + + +/*-----------------------------------------------------------------*/ +/* freeOperand - frees an operand */ +/*-----------------------------------------------------------------*/ +void freeOperand(operand * op) +{ + freeOpFromReg(op); + freeOpFromMem(op); +} + +/*-----------------------------------------------------------------*/ +/* nFreeRegs - returns number of free registers */ +/*-----------------------------------------------------------------*/ +static int nFreeRegs(void) +{ + int i; + int nfr = 0; + + for (i = pblaze_fReg; i < pblaze_nRegs; i++) + if (regsPBLAZE[i].isFree && regsPBLAZE[i].isReserved == 0) + nfr++; + return nfr; +} + +/*-----------------------------------------------------------------*/ +/* resetRegs - clear GP registers */ +/*-----------------------------------------------------------------*/ +void resetRegs(void) +{ + int i; + + for (i = pblaze_fReg; i < pblaze_nRegs; i++) { + if (!regsPBLAZE[i].isReserved) + freeReg(®sPBLAZE[i]); + } +} + +/*-----------------------------------------------------------------*/ +/* clearUnusedOpFromReg - remove old operands from the registers */ +/*-----------------------------------------------------------------*/ +int clearUnusedOpFromReg(iCode * ic) +{ + int position, freed = 0, i = 0; + if (!ic) + return 0; + + position = ic->seq; + + for (i = pblaze_fReg; i < pblaze_nRegs; i++) { + if (regsPBLAZE[i].isFree == 0 && regsPBLAZE[i].isReserved == 0 && regsPBLAZE[i].currOper && + !isOpVolatile(regsPBLAZE[i].currOper) && OP_LIVETO(regsPBLAZE[i].currOper) < position) { + if (!IS_OP_GLOBAL(regsPBLAZE[i].currOper) && OP_LIVEFROM(regsPBLAZE[i].currOper) > 0) { + freeOpFromReg(regsPBLAZE[i].currOper); + if (i >= SEND_REG_FIRST) + regsPBLAZE[i].isReserved = 1; + freed++; + } + } + } + + return freed; +} + +/*-----------------------------------------------------------------*/ +/* clearUnusedOpFromMem - remove old operands from the memory */ +/*-----------------------------------------------------------------*/ +int clearUnusedOpFromMem(iCode * ic) +{ + int position, freed = 0, i = 0; + if (!ic) + return 0; + + position = ic->seq; + for (i = 0; i < MEMSIZE; i++) { + + if (memPBLAZE[i].isFree == 0 && memPBLAZE[i].currOper && !IS_OP_GLOBAL(memPBLAZE[i].currOper) && + OP_LIVETO(memPBLAZE[i].currOper) != 0 && OP_LIVETO(memPBLAZE[i].currOper) < position) { + + freeMem(&memPBLAZE[i]); + freed++; + } + } + + return freed; +} + +/*-----------------------------------------------------------------*/ +/* clearMemEndFunc - clear memory at the end of a current function */ +/*-----------------------------------------------------------------*/ +void clearMemEndFunc(void) +{ + int i; + + for (i = 0; i < MEMSIZE; i++) { + + if (memPBLAZE[i].isFree == 0 && memPBLAZE[i].currOper && !IS_OP_GLOBAL(memPBLAZE[i].currOper)) { + freeMem(&memPBLAZE[i]); + } + } +} + +/*-----------------------------------------------------------------*/ +/* getMemoryBlock - return last memory cell number with current size */ +/*-----------------------------------------------------------------*/ +int getMemoryBlock(int size) +{ + int i, count = 0; + + for (i = 0; i < MEMSIZE; i++) { + if (memPBLAZE[i].isFree == 1 && memPBLAZE[i].isGlobal == 0) { + count++; + if (size <= count) + return i; + } else { + count = 0; + } + } + + //werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "cannot allocate memory for a global variable"); + fprintf(stderr, "%s:%d: pblaze port error: cannot allocate memory for a global variable\n", __FILE__, __LINE__); + exit(1); + return -1; +} + + +/*-----------------------------------------------------------------*/ +/* set operand in registers as reserved */ +/*-----------------------------------------------------------------*/ +void setReserved(operand * oper) +{ + int size, i; + + if (oper->type != SYMBOL) + return; + + symbol *s = OP_SYMBOL(oper); + size = getSize(s->type); + + if (s->nRegs == 0) + return; + + for (i = 0; i < size; i++) { + + s->regs[i]->isReserved = 1; + + } +} + +/*-----------------------------------------------------------------*/ +/* unset operand in registers as reserved */ +/*-----------------------------------------------------------------*/ +void unSetReserved(operand * oper) +{ + int size, i; + + if (oper->type != SYMBOL) + return; + + symbol *s = OP_SYMBOL(oper); + size = getSize(s->type); + + if (s->nRegs == 0) + return; + + for (i = 0; i < size; i++) { + if (s->regs[i]->rIdx < pblaze_nRegs) + s->regs[i]->isReserved = 0; + + } +} + +/*-----------------------------------------------------------------*/ +/* allocOpInMem - alloc operand in the memory */ +/*-----------------------------------------------------------------*/ +void allocOpInMem(operand * op) +{ + int size, i, pos, next = -1; + memMap *m; + + if (isOpInMem(op)) + return; + + size = getSize(operandType(op)); + pos = getMemoryBlock(size); + + for (i = 0; i < size; i++) { + m = &memPBLAZE[pos]; + m->currOper = op; + m->isFree = 0; + m->isGlobal = IS_OP_GLOBAL(op); + m->offset = i; + m->ptrOffset = 0; + m->nextPart = next; + next = pos--; + } + +} + + + +/*-----------------------------------------------------------------*/ +/* moveOpToMem - move operand from registers to memory */ +/*-----------------------------------------------------------------*/ +void moveOpToMem(operand * op) +{ + if (!op) { + return; + } + + int size, i, next = -1; + memMap *m, *t; + symbol *s = OP_SYMBOL(op); + + size = getSize(s->type); + + for (i = size - 1; i >= 0; i--) { + /* this offset is in the memory */ + if (s->regs[i] == NULL && (t = isOffsetInMem(op, i)) != NULL) { + next = t->addr; + } + /* offset is in the registers */ + else if (s->regs[i]) { + // try to get a pointer, if it is a global variable + if (IS_OP_GLOBAL(op) && (m = isOffsetInMem(op, i)) != NULL) { + } else + m = firstFreeMem(); + + if (!m) { + fprintf(stderr, "%s:%d: pblaze port error: not enough memory\n", __FILE__, __LINE__); + exit(1); + } + //emitcode ("STORE", "%s, %02x", s->regs[i]->name , m->addr ); + emitStore(s->regs[i]->name, m->addr); + + m->currOper = op; + m->isFree = 0; + m->isGlobal = IS_OP_GLOBAL(op); + m->offset = i; + m->ptrOffset = s->regs[i]->ptrOffset; + m->nextPart = next; + next = m->addr; + } + } + + freeOpFromReg(op); +} + +/*-----------------------------------------------------------------*/ +/* moveOffsetToMem - move operand's offset from registers to memory*/ +/*-----------------------------------------------------------------*/ +void moveOffsetToMem(operand * op, int offset) +{ + if (!op) { + return; + } + + memMap *m, *t; + symbol *s = OP_SYMBOL(op); + + // move all registers if it is a global operand + if (IS_OP_GLOBAL(op)) + moveOpToMem(op); + + // not a global operand + else if (offset >= 0 && s->regs[offset] != NULL) { + m = isOffsetInMem(op, offset); + if (!m) + m = firstFreeMem(); + + if (!m) { + fprintf(stderr, "%s:%d: pblaze port error: not enough memory\n", __FILE__, __LINE__); + exit(1); + } + //emitcode ("STORE", "%s, %02x", s->regs[offset]->name , m->addr ); + emitStore(s->regs[offset]->name, m->addr); + + m->currOper = op; + m->isFree = 0; + m->isGlobal = IS_OP_GLOBAL(op); + m->offset = offset; + m->ptrOffset = s->regs[offset]->ptrOffset; + t = isOffsetInMem(op, offset + 1); + if (t == NULL) + m->nextPart = -1; + else + m->nextPart = t->addr; + + // free operand's offset + freeOffsetFromReg(op, offset); + } +} + + +/*-----------------------------------------------------------------*/ +/* bitVectRemainRegs - returns sum of a bit values */ +/*-----------------------------------------------------------------*/ +int bitVectRemainRegs(bitVect * bv) +{ + int i, c = 0; + + if (!bv) + return 0; + + for (i = 0; i < bv->size; i++) + c += bitVectBitValue(bv, i); + return c; +} + + +/*-----------------------------------------------------------------*/ +/* firstIC5 - returns iCode of the first instruction from IC5 instr*/ +/*-----------------------------------------------------------------*/ +iCode *firstIC5(iCode * ic) +{ + iCode *tic; + if (!ic) + return NULL; + + tic = ic; + while (tic) { + if (SKIP_IC5(tic)) + break; + + tic = tic->next; + } + return tic; +} + +/*-----------------------------------------------------------------*/ +/* blockStart - returns iCode of the start of a block */ +/*-----------------------------------------------------------------*/ +iCode *blockStart(iCode * ic) +{ + iCode *tic; + if (!ic) + return NULL; + + tic = ic; + while (tic->prev) { + if (SKIP_IC2(tic->prev) || tic->prev->op == IFX) + break; + + tic = tic->prev; + } + return tic; +} + +/*-----------------------------------------------------------------*/ +/* blockEnd - returns iCode of the end of a block */ +/*-----------------------------------------------------------------*/ +iCode *blockEnd(iCode * ic) +{ + iCode *tic; + if (!ic) + return NULL; + + tic = ic; + while (tic->next) { + if (SKIP_IC2(tic->next) || tic->next->op == IFX) + break; + + tic = tic->next; + } + return tic; +} + +/*-----------------------------------------------------------------*/ +/* assignOptTest - checking whether the assignment can be optimized*/ +/* there can be some conflict in IFX */ +/*-----------------------------------------------------------------*/ +int testIFXConflict(iCode * lic, operand * to) +{ + iCode *ic, *ifxs, *ifxe; + short isIFX = 0; + short isIFEND = 0; + short isAssign = 0; + short isGoto = 0; + + if (!lic) + return 1; + + /* check whether we are nested in ifx */ + for (ic = lic; ic; ic = ic->prev) { + + if (ic->op == IFX) { + isIFX = 1; + ifxs = ic; + break; + } else if (IS_ENDLABEL(ic)) + break; + } + + if (!isIFX) + return 1; + + /* find end of the current IFX */ + for (ic = lic->next; ic; ic = ic->next) { + if (IS_ENDLABEL(ic)) { + isIFEND = 1; + ifxe = ic; + break; + } + } + + if (!isIFEND) + return 0; + + /* find assing conflicts (forward) */ + for (ic = lic->next; ic && ic != ifxe; ic = ic->next) { + if (ic->op == GOTO) + isGoto = 1; + else if (!SKIP_NO_OP(ic) && isGoto) { + if (IC_RESULT(ic) && pblaze_operandsEqu(to, IC_RESULT(ic))) + return 0; + else if (IC_RIGHT(ic) && pblaze_operandsEqu(to, IC_RIGHT(ic))) + return 0; + else if (IC_LEFT(ic) && pblaze_operandsEqu(to, IC_LEFT(ic))) + return 0; + } + } + + isGoto = 0; + + /* find assing conflicts (backward) */ + for (ic = lic; ic && ic != ifxs; ic = ic->prev) { + if (ic->op == GOTO) + isGoto = 1; + else if (IS_ENDLABEL(ic)) + break; + else if (!SKIP_NO_OP(ic) && isGoto) { + if (IC_RESULT(ic) && pblaze_operandsEqu(to, IC_RESULT(ic))) + return 0; + else if (IC_RIGHT(ic) && pblaze_operandsEqu(to, IC_RIGHT(ic))) + return 0; + else if (IC_LEFT(ic) && pblaze_operandsEqu(to, IC_LEFT(ic))) + return 0; + } + } + + return 1; +} + + +/*-----------------------------------------------------------------*/ +/* testOperand - LRU operands testing */ +/*-----------------------------------------------------------------*/ +void testOperand(operand * op, int free, bitVect * rUse) +{ + int sizeInReg, remainOp, size, j; + reg_info *r; + + if (!op) + return; + + sizeInReg = isOpInReg(op); + remainOp = bitVectRemainRegs(rUse); + + if (sizeInReg > 0 && remainOp - sizeInReg >= free) { + size = getSize(operandType(op)); + + for (j = 0; j < size; j++) { + r = isOffsetInReg(op, j); + if (r) { + bitVectUnSetBit(rUse, r->rIdx); + } + } + + } +} + +int isUsedInCurrentInstr(iCode * ic, operand * op) +{ + int res = 0; + + if (IC_LEFT(ic) != NULL && pblaze_operandsEqu(IC_LEFT(ic), op)) { + res = 1; + } + + else if (IC_RIGHT(ic) != NULL && pblaze_operandsEqu(IC_RIGHT(ic), op)) { + res = 1; + } + + else if (IC_RESULT(ic) != NULL && pblaze_operandsEqu(IC_RESULT(ic), op)) { + res = 1; + } + + return res; +} + +/*-----------------------------------------------------------------*/ +/* spillRegsIntoMem - move LRU operand into memory */ +/*-----------------------------------------------------------------*/ +int spillRegsIntoMem(iCode * lic, operand * op, int offset, int free) +{ + iCode *ic, *tic; + bitVect *rUse; + int remainOp, i, bStart; + + if (!lic) + return -1; + if (free <= 0) + return 0; + + // bit vector of used registers + rUse = newBitVect(pblaze_nRegs); + + tic = blockStart(lic); + if (tic) + bStart = tic->seq; + else + bStart = lic->seq; + + // set vector bits corresponding to used / free registers + for (i = pblaze_fReg; i < pblaze_nRegs; i++) { + if (regsPBLAZE[i].isReserved == 1 || regsPBLAZE[i].isFree == 1 || (bStart > OP_LIVEFROM(regsPBLAZE[i].currOper)) + || (isUsedInCurrentInstr(lic, regsPBLAZE[i].currOper) && regsPBLAZE[i].offset == offset)) { + bitVectUnSetBit(rUse, i); + } else { + bitVectSetBit(rUse, i); + } + } + + if (bitVectRemainRegs(rUse) == 0) { + return 1; + } + // get LRU operand + for (ic = lic; ic; ic = ic->next) { + + if (!SKIP_NO_OP(ic)) { + + if (IC_LEFT(ic) != NULL) { + testOperand(IC_LEFT(ic), free, rUse); + } + + if (IC_RIGHT(ic) != NULL) { + testOperand(IC_RIGHT(ic), free, rUse); + } + + if (IC_RESULT(ic) != NULL) { + testOperand(IC_RESULT(ic), free, rUse); + } + + } + + remainOp = bitVectRemainRegs(rUse); + + if (remainOp == free) + break; + } + + // try to move global variable first + for (i = pblaze_fReg; i < pblaze_nRegs; i++) { + if (bitVectBitValue(rUse, i) && IS_OP_GLOBAL(regsPBLAZE[i].currOper) && free > nFreeRegs()) { + moveOpToMem(regsPBLAZE[i].currOper); + } + } + + // move LRU temp variable into memory + for (i = pblaze_fReg; i < pblaze_nRegs; i++) { + if (bitVectBitValue(rUse, i) && free > nFreeRegs()) { + moveOffsetToMem(regsPBLAZE[i].currOper, regsPBLAZE[i].offset); + } + } + + ////////////////////////////////////////////////////////////////////////////////////////// + // second selection phase - operand with no assignment conflict (inside IF-ELSE condition) + if (remainOp == free) + return 0; + + /* + + // set vector bits corresponding to used / free registers + for (i = pblaze_fReg; i < pblaze_nRegs; i++) { + if( regsPBLAZE[i].isReserved == 1 || regsPBLAZE[i].isFree == 1 ) { + bitVectUnSetBit(rUse,i); + } + else { + bitVectSetBit(rUse,i); + } + } + + for (ic = lic; ic; ic = ic->next) { + + if( !SKIP_NO_OP(ic) ) { + + if(IC_LEFT(ic) != NULL && isOpInReg(IC_LEFT(ic)) && !testIFXConflict(ic, IC_LEFT(ic)) ) { + testOperand(IC_LEFT(ic), 0, rUse); + } + + if(IC_RIGHT(ic) != NULL && isOpInReg(IC_RIGHT(ic)) && !testIFXConflict(ic, IC_RIGHT(ic)) ) { + testOperand(IC_RIGHT(ic), 0, rUse); + } + + if(IC_RESULT(ic) != NULL && isOpInReg(IC_RESULT(ic)) && !testIFXConflict(ic, IC_RESULT(ic)) ) { + testOperand(IC_RESULT(ic), 0, rUse); + } + + } + } + + // move LRU temp variable into memory + for (i = pblaze_fReg; i < pblaze_nRegs; i++) { + if(bitVectBitValue(rUse,i) && free > nFreeRegs() ) { + moveOffsetToMem (regsPBLAZE[i].currOper, regsPBLAZE[i].offset); + } + } + + remainOp = bitVectRemainRegs(rUse); + + */ + + if (nFreeRegs() < free) { + return 1; + } + + return 0; +} + +/*-----------------------------------------------------------------*/ +/* globalChanged - global value changed */ +/*-----------------------------------------------------------------*/ +void globalChanged(operand * op, short c) +{ + int i, size; + + if (!op) + return; + + size = getSize(operandType(op)); + + for (i = 0; i < size; i++) { + if (OP_SYMBOL(op)->regs[i]) { + OP_SYMBOL(op)->regs[i]->changed = c; + } + } + +} + +/*-----------------------------------------------------------------*/ +/* freeGlobalsFromReg - move globals into the memory if changed */ +/*-----------------------------------------------------------------*/ +void freeGlobalsFromReg(void) +{ + int i; + + for (i = pblaze_fReg; i < pblaze_nRegs; i++) { + if (regsPBLAZE[i].currOper && IS_OP_GLOBAL(regsPBLAZE[i].currOper)) { + if (regsPBLAZE[i].changed == IN_REG) { + moveOpToMem(regsPBLAZE[i].currOper); + } else + freeOpFromReg(regsPBLAZE[i].currOper); + } + } + + +} + +/*-----------------------------------------------------------------*/ +/* getReg - returns pointer to a free register */ +/*-----------------------------------------------------------------*/ +reg_info *getReg(iCode * ic) +{ + reg_info *rtmp; + + clearUnusedOpFromReg(ic); + + rtmp = firstFreeReg(); + if (rtmp) { + /* callee saves */ + if (isCalleesaves()) { + if (!isRegUsed(rtmp->rIdx)) { + pushStack(rtmp->rIdx, 0); + } + setRegUsed(rtmp->rIdx); + } + + return rtmp; + } else { + rtmp = pblaze_regWithIdx(pblaze_nRegs + ctr); + + ctr++; + if (ctr >= SEND_REG_COUNT) + ctr = 0; + + return rtmp; + } + return NULL; +} + +/*-----------------------------------------------------------------*/ +/* getTempReg - returns pointer to a next temp register */ +/*-----------------------------------------------------------------*/ +reg_info *getTempReg(void) +{ + reg_info *rtmp; + rtmp = pblaze_regWithIdx(pblaze_nRegs + ctr); + + ctr++; + if (ctr >= SEND_REG_COUNT) + ctr = 0; + + return rtmp; +} + +/*-----------------------------------------------------------------*/ +/* getRegOper - returns pointer to a free register */ +/*-----------------------------------------------------------------*/ +reg_info *getRegOper(iCode * ic, operand * op, int offset) +{ + reg_info *rtmp; + + clearUnusedOpFromReg(ic); + if (nFreeRegs() == 0) { + + spillRegsIntoMem(ic, op, offset, 1); + + } + + rtmp = firstFreeReg(); + if (rtmp) { + /* callee saves */ + if (isCalleesaves()) { + if (!isRegUsed(rtmp->rIdx)) { + pushStack(rtmp->rIdx, 0); + } + setRegUsed(rtmp->rIdx); + } + + return rtmp; + } else { + rtmp = pblaze_regWithIdx(pblaze_nRegs + ctr); + + ctr++; + if (ctr >= SEND_REG_COUNT) + ctr = 0; + + return rtmp; + } + return NULL; +} + + +/*-----------------------------------------------------------------*/ +/* assignOptTest - checking whether the assignment can be optimized*/ +/* there can be some conflict in IFX */ +/*-----------------------------------------------------------------*/ +int assignOptTest(iCode * lic, operand * to) +{ + iCode *ic, *ifxs, *ifxe; + short isIFX = 0; + short isIFEND = 0; + short isAssign = 0; + short isGoto = 0; + + if (!lic) + return 1; + + /* check whether we are nested in ifx */ + for (ic = lic; ic; ic = ic->prev) { + + if (ic->op == IFX) { + isIFX = 1; + ifxs = ic; + break; + } else if (IS_ENDLABEL(ic)) + break; + } + + if (!isIFX) + return 1; + + /* find end of the current IFX */ + for (ic = lic->next; ic; ic = ic->next) { + if (IS_ENDLABEL(ic)) { + isIFEND = 1; + ifxe = ic; + break; + } + } + + if (!isIFEND) + return 0; + + /* find assing conflicts (forward) */ + for (ic = lic->next; ic && ic != ifxe; ic = ic->next) { + if (ic->op == GOTO) + isGoto = 1; + else if (ic->op == '=' && isGoto && pblaze_operandsEqu(to, IC_RESULT(ic))) { + return 0; + } + } + + isGoto = 0; + + /* find assing conflicts (backward) */ + for (ic = lic; ic && ic != ifxs; ic = ic->prev) { + if (ic->op == GOTO) + isGoto = 1; + else if (IS_ENDLABEL(ic)) + break; + else if (ic->op == '=' && isGoto && pblaze_operandsEqu(to, IC_RESULT(ic))) { + return 0; + } + } + + return 1; +} + +/*-----------------------------------------------------------------*/ +/* assignOpt - assign optimalization */ +/*-----------------------------------------------------------------*/ +void assignOpt(iCode * ic, operand * to, operand * from) +{ + int size, nReg, i; + reg_info *rtmp; + memMap *mem; + + if (IS_OP_GLOBAL(to)) + freeOpFromReg(to); + else + freeOperand(to); + + size = getSize(operandType(to)); + nReg = getSize(operandType(from)); + OP_SYMBOL(to)->nRegs = size; + + if (nReg == 0) { + return; + } + + for (i = 0; i < size; i++) { + + rtmp = OP_SYMBOL(from)->regs[i]; + if (!rtmp) { + mem = isOffsetInMem(from, i); + if (mem != NULL) + mem->currOper = to; + else { + //exit (1); + rtmp = getReg(ic); + if (rtmp->rIdx < pblaze_nRegs) { + rtmp->isFree = 0; + rtmp->offset = i; + //emitLoadNumb(rtmp->name, 0); + } + } + } + OP_SYMBOL(to)->regs[i] = rtmp; + if (rtmp) { + rtmp->currOper = to; + } + OP_SYMBOL(from)->regs[i] = NULL; + } + + for (i = size; i < nReg; i++) { + rtmp = OP_SYMBOL(from)->regs[i]; + freeReg(rtmp); + OP_SYMBOL(from)->regs[i] = NULL; + } + + OP_SYMBOL(from)->nRegs = 0; +} + + + +/*-----------------------------------------------------------------*/ +/* aopGetReg - assign an operand's offset into registers if necessary*/ +/* and returns that register */ +/*-----------------------------------------------------------------*/ +reg_info *aopGetReg(iCode * ic, operand * op, int offset) +{ + reg_info *rs; + int size; + memMap *mem, *mtmp; + reg_info *rtmp; + + // symbol only + if (op->type == SYMBOL) { + size = getSize(OP_SYMBOL(op)->type); + if (offset >= size) + return NULL; + + /* operand is already in the registers */ + if (OP_SYMBOL(op)->regs[offset] != NULL && OP_SYMBOL(op)->regs[offset]->rIdx < pblaze_nRegs) { + rs = OP_SYMBOL(op)->regs[offset]; + return rs; + } + // operand is in the memory + else if ((mem = isOffsetInMem(op, offset)) != NULL) { + + // get a register for the operand + if (mem->isOnlyInMem) + rtmp = getTempReg(); + else { + rtmp = getRegOper(ic, op, offset); + rtmp->ptrOffset = mem->ptrOffset; + } + + // no free registers, make this offset being pernament in the memory + if (rtmp->rIdx >= pblaze_nRegs && !IS_OP_GLOBALVOLATILE(op)) { + mem->isOnlyInMem = 1; + OP_SYMBOL(op)->regs[offset] = rtmp; + } + + if (mem->isOnlyInMem == 0) { + rtmp->isFree = 0; + rtmp->currOper = op; + rtmp->offset = offset; + + OP_SYMBOL(op)->regs[offset] = rtmp; + } + // load operand from the memory into registers + if (((ic->prev || ic->next))) + emitFetch(rtmp->name, mem->addr); + + // clear memory, if its a temporary variable + //if( !IS_OP_GLOBAL(op) ) IS_ITEMP(op) && OP_LIVETO(op) != 0 + if (!IS_OP_GLOBAL(op) && OP_LIVETO(op) != 0 && mem->isOnlyInMem == 0) + freeOffsetFromMem(op, offset); + + return rtmp; + } + // not in registers or the memory + else { + rtmp = getRegOper(ic, op, offset); + + // enought free registers + if (rtmp->rIdx < pblaze_nRegs) { + rtmp->isFree = 0; + rtmp->currOper = op; + rtmp->offset = offset; + rtmp->ptrOffset = 0; + + OP_SYMBOL(op)->regs[offset] = rtmp; + OP_SYMBOL(op)->nRegs = size; + + } + // not enought free registers - use memory for storing the operand + else { + mem = firstFreeMem(); + if (!mem) { + fprintf(stderr, "%s:%d: pblaze port error: not enough memory\n", __FILE__, __LINE__); + exit(1); + } + + OP_SYMBOL(op)->nRegs = size; + OP_SYMBOL(op)->regs[offset] = rtmp; + mem->currOper = op; + mem->offset = offset; + mem->ptrOffset = 0; + mem->isOnlyInMem = 1; + mem->isFree = 0; + mem->isGlobal = IS_OP_GLOBAL(op); + + mtmp = isOffsetInMem(op, offset + 1); + mem->nextPart = mtmp == NULL ? -1 : mtmp->addr; + mtmp = isOffsetInMem(op, offset - 1); + if (mtmp) + mtmp->nextPart = mem->addr; + + } + + rs = rtmp; + return rs; + } + } + return NULL; +} + +/*-----------------------------------------------------------------*/ +/* aopGetRegName - assign an operand's offset into registers */ +/* if necessary and returns that register's name */ +/*-----------------------------------------------------------------*/ +char *aopGetRegName(iCode * ic, operand * op, int offset) +{ + reg_info *rs; + rs = aopGetReg(ic, op, offset); + return rs != NULL ? rs->name : NULL; +} + +/*-----------------------------------------------------------------*/ +/* aopUpdateOpInMeme - save value of operand which is pernamently */ +/* in the memory (due to no free registers ) */ +/*-----------------------------------------------------------------*/ +void aopUpdateOpInMem(iCode * ic, operand * op, int offset) +{ + memMap *mem; + + mem = isOffsetInMem(op, offset); + + if (mem && mem->isOnlyInMem == 1 && OP_SYMBOL(op) && OP_SYMBOL(op)->regs[offset] != NULL + && !IS_OP_GLOBALVOLATILE(op)) { + emitStore(OP_SYMBOL(op)->regs[offset]->name, mem->addr); + OP_SYMBOL(op)->regs[offset] = NULL; + } +} + +/*-----------------------------------------------------------------*/ +/* aopMoveReg - move register to an operand */ +/*-----------------------------------------------------------------*/ +void aopMoveReg(iCode * ic, operand * result, reg_info * rFrom, int offset) +{ + memMap *mem; + reg_info *reg; + + if (result->type == SYMBOL) { + if (rFrom->rIdx >= pblaze_nRegs) { + mem = isOffsetInMem(result, offset); + + if ((mem && mem->isOnlyInMem == 1) || (mem && !isOffsetInReg(result, offset))) { + emitStore(rFrom->name, mem->addr); + } else { + reg = aopGetReg(ic, result, offset); + if (reg->rIdx >= pblaze_nRegs) { + emitLoad(reg->name, rFrom->name); + aopUpdateOpInMem(ic, result, offset); + } else { + emitLoad(reg->name, rFrom->name); + } + + } + } else { + if (rFrom->currOper && IS_SYMOP(rFrom->currOper)) + OP_SYMBOL(rFrom->currOper)->regs[rFrom->offset] = NULL; + + mem = isOffsetInMem(result, offset); + if (mem && mem->isOnlyInMem == 1) { + emitStore(rFrom->name, mem->addr); + } else { + rFrom->isFree = 0; + rFrom->currOper = result; + rFrom->offset = offset; + rFrom->ptrOffset = 0; + + OP_SYMBOL(result)->regs[offset] = rFrom; + } + } + } +} + +/*-----------------------------------------------------------------*/ +/* aopPutReg */ +/*-----------------------------------------------------------------*/ +void aopPutReg(iCode * ic, operand * result, reg_info * rFrom, int offset) +{ + reg_info *res; + memMap *mem; + + if (result->type == SYMBOL) { + + if (IS_OP_GLOBALVOLATILE(result) || (result->isaddr && LOCAL_POINTER)) { + mem = isOffsetInMem(result, offset); + if (mem) + emitStore(rFrom->name, mem->addr); + else + fprintf(stderr, "%s:%d: pblaze port warning: operand %s is not in the memory\n", __FILE__, __LINE__, + OP_SYMBOL(result)->name); + } + + else if (IS_OP_GLOBAL(result)) { + lockReg(rFrom); + mem = isOffsetInMem(result, offset); + if (mem && mem->isOnlyInMem == 1) { + emitStore(rFrom->name, mem->addr); + return; + } + + res = aopGetReg(ic, result, offset); + if (res->rIdx >= pblaze_nRegs && mem) { + emitStore(rFrom->name, mem->addr); + } else + emitLoad(res->name, rFrom->name); + unlockReg(rFrom); + } + /* result is a pointer into memory */ + else if (POINTER_SET(ic)) { + if(isInOutRef(result)) { + pblaze_emitcodeOutput(ic, rFrom->name, result); + } + else { + res = aopGetReg(ic, result, 0); + + /* move value into a pointed memory */ + emitStoreReg(rFrom->name, res->name); + res->ptrOffset = offset; + } + } + /* normal operation */ + else { + /* temporarly source register (unassigned to any operand) */ + if (rFrom->isReserved == 1 && SEND_REG_FIRST > rFrom->rIdx && !rFrom->currOper) { + aopMoveReg(ic, result, rFrom, offset); + } else { + res = aopGetReg(ic, result, offset); + mem = isOffsetInMem(result, offset); + /* operand only in memory */ + if (mem && mem->isOnlyInMem && rFrom->rIdx >= pblaze_nRegs) { + emitStore(rFrom->name, mem->addr); + } + /* normal operation */ + else { + if (strcmp(res->name, rFrom->name) != 0) + emitLoad(res->name, rFrom->name); + aopUpdateOpInMem(ic, result, offset); + } + } + } + } +} + +/*-----------------------------------------------------------------*/ +/* aopPutVal */ +/*-----------------------------------------------------------------*/ +void aopPutVal(iCode * ic, operand * result, char *val, int offset) +{ + reg_info *rtmp, *res; + memMap *mem; + + if (result->type == SYMBOL) { + + if (IS_OP_GLOBALVOLATILE(result) || (result->isaddr && LOCAL_POINTER)) { + mem = isOffsetInMem(result, offset); + if (mem) { + rtmp = getReg(ic); + lockReg(rtmp); + emitLoad(rtmp->name, val); + emitStore(rtmp->name, mem->addr); + unlockReg(rtmp); + } else + fprintf(stderr, "%s:%d: pblaze port warning: operand %s is not in the memory\n", __FILE__, __LINE__, + OP_SYMBOL(result)->name); + } + + else if (IS_OP_GLOBAL(result)) { + res = aopGetReg(ic, result, offset); + emitLoad(res->name, val); + + if (res->rIdx >= pblaze_nRegs) { + mem = isOffsetInMem(result, offset); + if (mem && mem->isOnlyInMem == 1) { + emitStore(res->name, mem->addr); + } + } + + } + + /* result is a pointer into memory */ + else if (POINTER_SET(ic)) { + + if(isInOutRef(result)) { + rtmp = getReg(ic); + emitLoad(rtmp->name, val); + pblaze_emitcodeOutput(ic, rtmp->name, result); + } + else { + res = aopGetReg(ic, result, 0); + + /* move value into a pointed memory */ + rtmp = getReg(ic); + emitLoad(rtmp->name, val); + emitStoreReg(rtmp->name, res->name); + res->ptrOffset = offset; + } + } + /* basic load into a register */ + else { + res = aopGetReg(ic, result, offset); + + emitLoad(res->name, val); + aopUpdateOpInMem(ic, result, offset); + } + + } + //Safe_free(val); +} + +/*-----------------------------------------------------------------*/ +/* findAndAllocGlobals - alloc memory for global variables */ +/*-----------------------------------------------------------------*/ +static void findAndAllocGlobals(iCode * lic) +{ + iCode *ic; + operand *op; + + if (!lic) + return; + + for (ic = lic; ic; ic = ic->next) { + if (!SKIP_NO_OP(ic)) { + + if (IC_LEFT(ic) && (IS_OP_GLOBAL(IC_LEFT(ic)))) { + op = IC_LEFT(ic);; + if (!IS_FUNC(OP_SYM_TYPE(op)) && !isOpInMem(op)) + allocOpInMem(op); + } + + if (IC_RIGHT(ic) && (IS_OP_GLOBAL(IC_RIGHT(ic)))) { + op = IC_RIGHT(ic); + if (!IS_FUNC(OP_SYM_TYPE(op)) && !isOpInMem(op)) + allocOpInMem(op); + } + + if (IC_RESULT(ic) && (IS_OP_GLOBAL(IC_RESULT(ic)))) { + op = IC_RESULT(ic); + if (!IS_FUNC(OP_SYM_TYPE(op)) && !isOpInMem(op)) + allocOpInMem(op); + } + } + } + +} + +/*-----------------------------------------------------------------*/ +/* findIndirectOperands - alloc memory for arrays or pointed operands*/ +/*-----------------------------------------------------------------*/ +static void findIndirectOperands(iCode * lic) +{ + iCode *ic; + operand *op; + + if (!lic) + return; + + for (ic = lic; ic; ic = ic->next) { + + if (!SKIP_NO_OP(ic)) { + + // indirect address + if (IC_RESULT(ic) && IC_RESULT(ic)->isaddr && !IS_OP_GLOBAL(IC_RESULT(ic)) && + !isOpVolatile(IC_RESULT(ic)) && OP_LIVEFROM(IC_RESULT(ic)) == 0 && OP_LIVETO(IC_RESULT(ic)) == 0) { + op = IC_RESULT(ic); + if (!IS_FUNC(OP_SYM_TYPE(op)) && !isOpInMem(op)) + allocOpInMem(op); + } + + if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) && !isOpVolatile(IC_LEFT(ic)) && + (IS_ARRAY(OP_SYM_TYPE(IC_LEFT(ic))) || IS_STRUCT(OP_SYM_TYPE(IC_LEFT(ic))) + || IS_TYPEDEF(OP_SYM_TYPE(IC_LEFT(ic))) || (IC_LEFT(ic)->isaddr && !IS_ITEMP(IC_LEFT(ic))))) { + op = IC_LEFT(ic); + if (!IS_FUNC(OP_SYM_TYPE(op)) && !isOpInMem(op)) + allocOpInMem(op); + + } + } + } + +} + +/*-----------------------------------------------------------------*/ +/* pblaze_genCodeLoop */ +/*-----------------------------------------------------------------*/ +void pblaze_genCodeLoop(void) +{ + ebbIndex *ebbi; + eBBlock **ebbs; + int count; + iCode *ic; + + _G_glueCalled = 1; + pblaze_interrupt = NULL; + + if (_G_codeSet) { + + // optimalization phase + for (ebbi = setFirstItem(_G_codeSet); ebbi; ebbi = setNextItem(_G_codeSet)) { + ebbs = ebbi->bbOrder; + count = ebbi->count; + + /* now get back the chain */ + //ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count)); + ic = iCodeFromeBBlock(ebbs, count); + findAndAllocGlobals(ic); + } + + // code generation phase + for (ebbi = setFirstItem(_G_codeSet); ebbi; ebbi = setNextItem(_G_codeSet)) { + ebbs = ebbi->bbOrder; + count = ebbi->count; + + setToNull((void *) &_G.funcrUsed); + /* now get back the chain */ + ic = iCodeFromeBBlock(ebbs, count); + + findIndirectOperands(ic); + //resetRegs (); + + genPBLAZECode(ic); + resetRegs(); + } + } + +} + + + +/*-----------------------------------------------------------------*/ +/* assignRegisters */ +/*-----------------------------------------------------------------*/ +void pblaze_assignRegisters(ebbIndex * ebbi) +{ + eBBlock **ebbs = ebbi->bbOrder; + int count = ebbi->count; + iCode *ic; + + if (gInit == 0) { + gInit = 1; + initPBLAZEMem(); + } + //doOverlays (ebbs, count); + //iCodeLabelOptimize(iCodeFromeBBlock (ebbs, count) ); + + if (!_G_glueCalled) { + addSet(&_G_codeSet, ebbi); + + } else { + + + setToNull((void *) &_G.funcrUsed); + + /* now get back the chain */ + //ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count)); + ic = iCodeFromeBBlock(ebbs, count); + + //findAndAllocGlobals(ic); + + genPBLAZECode(ic); + } + return; +} diff -NaurbB sdcc-src-3.1.0/src/pblaze/ralloc.h sdcc-src-3.1.0-pblaze/src/pblaze/ralloc.h --- sdcc-src-3.1.0/src/pblaze/ralloc.h 1970-01-01 01:00:00.000000000 +0100 +++ sdcc-src-3.1.0-pblaze/src/pblaze/ralloc.h 2011-12-05 23:42:54.284169700 +0100 @@ -0,0 +1,142 @@ +/*------------------------------------------------------------------------- +ralloc.h - source file for register allocation. (XILINX PICOBLAZE) specific + +Author: + Jakub Hornik, xhorni00<at>stud.fit.vutbr.cz +Master Thesis Project: + Compiler Back-End of Subset of Language C for 8-Bit Processor +Date: + 2011 + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ +#include "SDCCicode.h" +#include "SDCCBBlock.h" +#ifndef PBLAZERALLOC_H +#define PBLAZERALLOC_H + +enum { + S0_IDX = 0, + S1_IDX, S2_IDX, S3_IDX, S4_IDX, + S5_IDX, S6_IDX, S7_IDX, S8_IDX, + S9_IDX, SA_IDX, SB_IDX, SC_IDX, + SD_IDX, SE_IDX, SF_IDX +}; + +enum { + SAME_VAL = 0, + IN_REG, + IN_MEM +}; + + +#define REG_PTR 0x01 +#define REG_GPR 0x02 /* general purpose registers */ + +/* definition of the stack size and the stack bottom */ +#define PBLAZE_STACK_SIZE 32 +#define PBLAZE_STACK_BOTTOM 0x3F + +/* first register used in send/receive function passing */ +#define SEND_REG_FIRST SB_IDX +/* number of send/receive registers */ +#define SEND_REG_COUNT 4 + +/* PicoBlaze's data memory size */ +#define MEMSIZE 64 +#define PBLAZENREGS 16 + +static set *_G_codeSet; +static int _G_glueCalled = 0; + +/* definition for the registers */ +typedef struct reg_info { + short type; /* PicoBlaze have only REG_GPR */ + short rIdx; /* index into register table */ + char *name; /* name */ + operand *currOper; /* current operand in the register */ + short offset; /* offset of the operand */ + short ptrOffset; /* offset of the current pointer */ + short changed; /* global variable is actual in the register */ + unsigned isFree:1; /* is currently unassigned */ + unsigned isReserved:1; /* is reserved */ +} reg_info; + + + +/* definition for the memory */ +typedef struct memMap { + unsigned int addr; /* address of the memory cell */ + operand *currOper; /* current operand in the register */ + short offset; /* offset of the operand (if larger than 1B) */ + short ptrOffset; /* offset of the current pointer */ + short nextPart; /* index into memory with next part of the operand */ + unsigned reserved:1; /* is reserved */ + unsigned isGlobal:1; /* contains global value */ + unsigned isFree:1; /* is currently free */ + unsigned isOnlyInMem:1; /* temporary variable which is only in the memory due to no avaiable registers */ +} memMap; + +extern reg_info regsPBLAZE[]; +extern memMap memPBLAZE[]; + +void staticMemoryCheck(int top); + +char *aopGetRegName(iCode * ic, operand * op, int offset); +reg_info *aopGetReg(iCode * ic, operand * op, int offset); +void aopPutReg(iCode * ic, operand * result, reg_info * rFrom, int offset); +void aopPutVal(iCode * ic, operand * result, char *val, int offset); +void aopMoveReg(iCode * ic, operand * result, reg_info * rFrom, int offset); +void aopUpdateOpInMem(iCode * ic, operand * op, int offset); + +reg_info *getReg(iCode * ic); + +int isOpInReg(operand * op); +reg_info *isOffsetInReg(operand * op, int offset); + +memMap *isOpInMem(operand * op); +memMap *isOffsetInMem(operand * op, int offset); + +void assignOpt(iCode * ic, operand * to, operand * from); +int assignOptTest(iCode * lic, operand * to); + +int clearUnusedOpFromReg(iCode * ic); +int clearUnusedOpFromMem(iCode * ic); +void clearMemEndFunc(void); +void globalChanged(operand * op, short c); +void freeGlobalsFromReg(void); +void allocOpInMem(operand * op); +void freeOpFromReg(operand * op); +memMap *firstFreeMem(void); +void moveOpToMem(operand * op); + +void printRegs(void); +void printMemory(void); +void printConstants(FILE * of); +char *operName(int addr); + +void setReserved(operand * oper); +void unSetReserved(operand * oper); +void unlockReg(reg_info * r); +void lockReg(reg_info * r); + +reg_info *pblaze_regWithIdx(int); +void pblaze_genCodeLoop(void); + +#endif diff -NaurbB sdcc-src-3.1.0/src/port.h sdcc-src-3.1.0-pblaze/src/port.h --- sdcc-src-3.1.0/src/port.h 2011-10-09 20:21:10.000000000 +0200 +++ sdcc-src-3.1.0-pblaze/src/port.h 2011-12-04 15:56:51.809631700 +0100 @@ -22,6 +22,7 @@ #define TARGET_ID_HC08 11 #define TARGET_ID_Z180 12 #define TARGET_ID_R2K 13 +#define TARGET_ID_PBLAZE 14 /* Macro to test the target we are compiling for. Can only be used after SDCCmain has defined the port @@ -38,6 +39,7 @@ #define TARGET_IS_XA51 (port->id == TARGET_ID_XA51) #define TARGET_IS_HC08 (port->id == TARGET_ID_HC08) #define TARGET_IS_R2K (port->id == TARGET_ID_R2K) +#define TARGET_IS_PBLAZE (port->id == TARGET_ID_PBLAZE) #define TARGET_MCS51_LIKE (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_DS400) #define TARGET_Z80_LIKE (TARGET_IS_Z80 || TARGET_IS_Z180 || TARGET_IS_GBZ80 || TARGET_IS_R2K) @@ -427,5 +429,8 @@ #if !OPT_DISABLE_HC08 extern PORT hc08_port; #endif +#if !OPT_DISABLE_PBLAZE +extern PORT pblaze_port; +#endif #endif /* PORT_INCLUDE */