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 */