OpenCores
URL https://opencores.org/ocsvn/copyblaze/copyblaze/trunk

Subversion Repositories copyblaze

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /copyblaze
    from Rev 50 to Rev 51
    Reverse comparison

Rev 50 → Rev 51

/trunk/copyblaze/sw/tools/comp/pbcc/sdcc-src-3.1.0.tar.bz2 Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
trunk/copyblaze/sw/tools/comp/pbcc/sdcc-src-3.1.0.tar.bz2 Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: trunk/copyblaze/sw/tools/comp/pbcc/sdcc-3.1.0-pblaze_[-NaurbB].patch =================================================================== --- trunk/copyblaze/sw/tools/comp/pbcc/sdcc-3.1.0-pblaze_[-NaurbB].patch (nonexistent) +++ trunk/copyblaze/sw/tools/comp/pbcc/sdcc-3.1.0-pblaze_[-NaurbB].patch (revision 51) @@ -0,0 +1,18950 @@ +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 ++ ++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 ++ ++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 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 ++ ++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 ++ * ++ * 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 ++ * ++*/ ++ ++#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 ++ * ++*/ ++ ++#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 ++ * ++*/ ++ ++#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 ++ * ++*/ ++ ++#ifndef __MATH_H__ ++#define __MATH_H__ ++ ++/* ++#pragma library math ++ ++#include ++ ++#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 ++ * ++ * $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 ++# Begin specification of device type , e.g. 18f6720. ++# Aliases 'p' and 'pic' will be recognized as well. ++# using ++# Import specification from the named entry, which must be defined ++# earlier. Later commands overrule imported ones. ++# ramsize ++# This device has bytes of RAM. ++# split ++# Addresses below refer to bank 0, addresses above ++# refer to SFRs in bank 15 for references via the access bank. ++# configrange ++# Configuration registers occupy addresses to (both ++# included). ++# configword
++# The config word at address
only implements the bits ++# indicated via (all others will be forced to 0 by the ++# compiler). ++# Unless overridden in C code, use the given default . ++# idlocrange ++# ID locations occupy addresses to (both included). ++# idword
++# Unless overridden in C code, use the given default . ++# ++ ++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 ++ * ++*/ ++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 ++ ++ 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 ++#include ++#include ++#include ++#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; iregs[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 ++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 ++ * ++ * 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 ++# include ++#endif /* STDC_HEADERS */ ++ ++#if HAVE_STRINGS_H ++# include ++#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 ++ * ++ * 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 ++ * ++ * 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 ++ * ++ * 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 header file. */ ++#define HAVE_FCNTL_H 1 ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_INTTYPES_H 1 ++ ++/* Define to 1 if you have the 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 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 header file. */ ++#define HAVE_STDINT_H 1 ++ ++/* Define to 1 if you have the 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 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 header file. */ ++#undef HAVE_STRINGS_H ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_STRING_H 1 ++ ++/* Define to 1 if you have the header file. */ ++#undef HAVE_SYSLOG_H ++ ++/* Define to 1 if you have the header file. */ ++#undef HAVE_SYS_PARAM_H ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_SYS_STAT_H 1 ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_SYS_TYPES_H 1 ++ ++/* Define to 1 if you have the 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 ++ * ++ * 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 ++#include ++#include ++#include ++ ++#if HAVE_SYSLOG_H ++# include ++#endif /* HAVE_SYSLOG_H */ ++ ++#if HAVE_UNISTD_H ++# include ++#endif /* HAVE_UNISTD_H */ ++ ++#if HAVE_SYS_PARAM_H ++#include ++#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 ++ * ++ * 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 ++ * ++ * 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 ++ * ++ * 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 ++#include ++#include ++#include ++ ++#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_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;jk); ++ 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_to_json_string(val, pb); } ++ } ++ indentDeep--; ++ if(indent) ++ { ++ sprintbuf(pb, "\n"); ++ for(j=0;jo.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 ++ * ++ * 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 ++ * ++ * 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 ++ * ++ * 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 ++#include ++#include ++#include ++#include ++ ++#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 ++ * ++ * 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 ++#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 ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++ ++#if HAVE_SYS_TYPES_H ++#include ++#endif /* HAVE_SYS_TYPES_H */ ++ ++#if HAVE_SYS_STAT_H ++#include ++#endif /* HAVE_SYS_STAT_H */ ++ ++#if HAVE_FCNTL_H ++#include ++#endif /* HAVE_FCNTL_H */ ++ ++#if HAVE_UNISTD_H ++# include ++#endif /* HAVE_UNISTD_H */ ++ ++#ifdef WIN32 ++# define WIN32_LEAN_AND_MEAN ++# include ++# include ++#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 ++ * ++ * 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 ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++ * ++ * 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 ++ * ++ * 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 ++#include ++#include ++ ++#if HAVE_STDARG_H ++# include ++#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 ++ * ++ * 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 */ ++/* /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; iisFree = 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, xhorni00stud.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 ++#include ++#include ++#include ++#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, xhorni00stud.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, xhorni00stud.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 ++#include ++#include ++#include ++#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, xhorni00stud.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, xhorni00stud.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, xhorni00stud.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 ++//#include "newalloc.h" ++#include ++#include ++#include "dbuf_string.h" ++ ++#ifdef _WIN32 ++#include ++#else ++#include ++#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, xhorni00stud.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, xhorni00stud.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, xhorni00stud.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 */ Index: trunk/copyblaze/sw/tools/comp/pbcc/sdcc-3.1.0-pblaze_[-rup].patch =================================================================== --- trunk/copyblaze/sw/tools/comp/pbcc/sdcc-3.1.0-pblaze_[-rup].patch (nonexistent) +++ trunk/copyblaze/sw/tools/comp/pbcc/sdcc-3.1.0-pblaze_[-rup].patch (revision 51) @@ -0,0 +1,251 @@ +diff -rup 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_Z80 = @OPT_DISABLE_Z80@ + 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 -rup 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_R2K + 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_pic16_port + enable_hc08_port + enable_avr_port + enable_xa51_port ++enable_pblaze_port + enable_ucsim + enable_device_lib + enable_packihx +@@ -1373,6 +1375,7 @@ Optional Features: + --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 @@ _ACEOF + + + ++ # 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 @@ if test $OPT_DISABLE_Z80 = 0 || test $OP + + 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 @@ do + "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 @@ sdcc ${VERSION} is now configured for + 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 @@ sdcc ${VERSION} is now configured for + 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 -rup 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(ds400, ds400, DS400, [Exclude + 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 @@ if test $OPT_DISABLE_Z80 = 0 || test $OP + 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 @@ sdcc ${VERSION} is now configured for + 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} +Only in sdcc-src-3.1.0-pblaze/device/examples: pblaze +diff -rup 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 @@ install: all installdirs + 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 @@ installcheck: + # --------------------------------- + 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 \ +Only in sdcc-src-3.1.0-pblaze/device/include: pblaze +diff -rup 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_XA51 = @OPT_DISABLE_XA51@ + 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 -rup 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_PIC14 = @OPT_DISABLE_PIC14@ + 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 \ +Only in sdcc-src-3.1.0-pblaze/doc: sdcc_pblaze_instructions.txt +diff -rup 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 -rup 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 -rup 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 @@ static PORT *_ports[] = { + #if !OPT_DISABLE_HC08 + &hc08_port, + #endif ++#if !OPT_DISABLE_PBLAZE ++ &pblaze_port, ++#endif + }; + + #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0])) +Only in sdcc-src-3.1.0-pblaze/src: json +Only in sdcc-src-3.1.0-pblaze/src: pblaze +diff -rup 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 @@ extern PORT ds400_port; + #if !OPT_DISABLE_HC08 + extern PORT hc08_port; + #endif ++#if !OPT_DISABLE_PBLAZE ++extern PORT pblaze_port; ++#endif + + #endif /* PORT_INCLUDE */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.