First off:
bash-3.1$ pgcc -V
pgcc 6.0-8 32-bit target on x86 Windows
Ok, Matlab defines some functions returning type bool which is typedef’d to unsigned char. I test these a lot in if statements. It looks like from comparing pgcc’s assembly to gcc’s assembly that the problem comes from the register testing. Using pgcc there’s junk left in the upper part of eax and thus the result is always true. Using gcc testing only the lower 8 bits (register AL) results in the correct answer. So, is this a pgcc bug (should only be testing AL), a Matlab bug (the mxIsEmpty function should initialize eax=0), or something I’ve missed?
Here is the assembly code produced from pgcc followed by the gcc assembly code, and lastly by snippets of the preprocessed C source code.
PGCC ASSEMBLY
.file “test.c”
PGC 6.0 -opt 1
PGC 06/15/2006 16:25:32
pgcc test.c -S -Ic:/matlab/r2006a/extern/include -Lc:/matlab/r2006a/bin/win32 -lmex -lmx
c:\PROGRA~1\PGI/nt86/6.0/bin/pgc.EXE test.c -opt 1 -terse 1 -inform warn
-x 19 0x400000 -x 119 0x40610400 -x 119 0x100000 -x 119 0x1000 -x 120 0x80
-x 122 0x40 -x 123 0x1000 -x 127 4 -x 80 0x300 -y 80 0x1000 -x 80 0x40000000
-x 119 0x1000000 -astype 1 -stdinc c:\PROGRA~1\PGI/nt86/6.0/include;c:\PROGRA~1\PGI/nt86/6.0/mingw/include;c:\PROGRA~1\PGI/nt86/6.0/mingw/mingw32/include;c:\PROGRA~1\PGI/nt86/6.0/mingw/lib/gcc-lib/mingw32/2.95.3-5/include
-def POSIX -def __POSIX -def POSIX -def WIN32 -def _WIN32 -def __WIN32
-def WIN32 -def WINNT -def __WINNT -def WINNT -def X86=1 -def MINGW32=1.0
-def MSVCRT -def __i386 -def i386 -def i386 -def nt86 -def unix
-predicate #machine(i386) #lint(off) #system(unix) #system(winnt) #cpu(i386)
-idir c:/matlab/r2006a/extern/include -cmdline +pgcc test.c -S -Ic:/matlab/r2006a/extern/include -Lc:/matlab/r2006a/bin/win32 -lmex -lmx
-asm test.s
lineno: 6
.text
.align 4
.long …EN1-_mexFunction+0xc8000000
.align 16
.globl _mexFunction
.def _mexFunction; .scl 2; .type 0x20; .endef
_mexFunction:
pushl %ebp
movl %esp,%ebp
subl $8,%esp
…EN1:
lineno: 7
movl 20(%ebp),%eax
movl (%eax),%edx
movl %edx,(%esp)
call _mxIsEmpty
testl %eax,%eax
je .LB635
movl $.S00636,%ecx
movl %ecx,(%esp)
call _mexPrintf
jmp .LB638
.LB635:
lineno: 10
movl $.S00639,%eax
movl %eax,(%esp)
call _mexPrintf
.LB638:
lineno: 11
movl %ebp,%esp
popl %ebp
ret
.data
.align 1
.S00639:
“!empty\n”
.byte 0x21,0x65,0x6d,0x70,0x74,0x79,0x0a,0x00
.S00636:
“empty\n”
.byte 0x65,0x6d,0x70,0x74,0x79,0x0a,0x00
.data
GCC ASSEMBLY
.file “test_gcc.c”
.section .rdata,“dr”
LC0:
.ascii “empty\12\0”
LC1:
.ascii “!empty\12\0”
.text
.globl _mexFunction
.def _mexFunction; .scl 2; .type 32; .endef
_mexFunction:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
movl 20(%ebp), %eax
movl (%eax), %eax
movl %eax, (%esp)
call _mxIsEmpty
testb %al, %al
je L2
movl $LC0, (%esp)
call _mexPrintf
jmp L1
L2:
movl $LC1, (%esp)
call _mexPrintf
L1:
leave
ret
.def _mexPrintf; .scl 3; .type 32; .endef
.def _mxIsEmpty; .scl 3; .type 32; .endef
\
C Source code
typedef unsigned char boolean_T ;
typedef boolean_T bool ;
[snip]
extern bool mxIsEmpty (
const mxArray * pa
) ;
[snip]
void mexFunction (
int nlhs ,
mxArray * plhs ,
int nrhs ,
const mxArray * prhs
) ;
[snip]
void mexFunction ( int nlhs , mxArray * plhs , int nrhs , const mxArray * prhs )
{
if ( mxIsEmpty ( prhs [ 0 ] ) )
mexPrintf ( “empty\n” ) ;
else
mexPrintf ( “!empty\n” ) ;
}