gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > Compiling into THUMB / ARM

#9601 - regularkid - Sun Aug 10, 2003 3:39 am

Hi. I've got a problem with compiling code into THUMB / ARM. I'm not very familiar with how the compiler really works and I've read the docs and FAQ at devrs but still can't seem to figure some things out. Any help would be great!

So, I'm mixing C code and ASM code and want to make sure that everything gets compiled to the right format / place in memory. I have been looking at my memory map that gets outputted from the compiler and it seems that code and constants are being placed into ROM (0x08000000 and up). This is cool, becuase it is where I want it to go. However, I want to make sure that it is compiling into THUMB code since it wouldn't be very smart to put ARM code into ROM seeing how it is 16bit memory and ARM opcodes are 32bit. Here is my makefile:

Code:

CC      =   gcc -mthumb-interwork
AS      =   as -mthumb-interwork

GCCARM  =   C:\DevKitAdv\bin
INCDIR  =   C:\DevKitAdv\include
LIBDIR  =   C:\DevKitAdv\lib

GAME   =   Game

CFILES   =   Debug.c               \
      Dma.c               \
      Input.c               \
      Irq.c               \
      Level.c               \
      Main.c               \
      Math.c               \
      Render.c            \
      Sprite.c            \
      Timer.c               \
      Video.c               \

SFILES   =   Video.S               \
      Render.S            \

OBJS   =   $(CFILES:.c=.o)            \
      $(SFILES:.S=_ASM.o)         \

ASFLAGS =   
CFLAGS   =   -c -Wall
LFLAGS   =   -TLinkscript -Wl,-Map,Memory_map

##############################################################
## RULES
##############################################################
Code : $(GAME).bin
   @ECHO
   @ECHO CODE BUILD COMPLETE!

$(GAME).bin : $(GAME).elf
   @ECHO
   @ECHO ----------------------------
   @ECHO Making Game binary...
   @objcopy -O binary $(GAME).elf $(GAME).bin

$(GAME).elf : $(OBJS)
   @ECHO Linking...
   @$(CC) $(LFLAGS) -o $(GAME).elf $(OBJS) -lc -lgcc -lm

%.o : %.c
   @ECHO Compiling $<...
   @$(CC) $(CFLAGS) $< -o $@

clean :
   @ECHO Cleaning files...
   @rm -f *.o

##############################################################
## DEPENDENCIES
##############################################################
include C:\Game\Dependencies\Debug.dpn
include C:\Game\Dependencies\Input.dpn
include C:\Game\Dependencies\Main.dpn
include C:\Game\Dependencies\Video.dpn
include C:\Game\Dependencies\Timer.dpn
include C:\Game\Dependencies\Dma.dpn
include C:\Game\Dependencies\Level.dpn
include C:\Game\Dependencies\Math.dpn
include C:\Game\Dependencies\Sprite.dpn
include C:\Game\Dependencies\Irq.dpn
include C:\Game\Dependencies\Render.dpn

Video_ASM.o : Video.S
   @ECHO Assembling Video.S...
   @$(AS) $(ASFLAGS) Video.S -o Video_ASM.o

Render_ASM.o : Render.S
   @ECHO Assembling Render.S...
   @$(AS) $(ASFLAGS) Render.S -o Render_ASM.o


Now, how would I make sure that the .c files get compiled into THUMB code instead of ARM. By the way, the linkscript file is just a generic one that I downloaded from the FAQ on devrs.

Next, here is the basic setup for all my ASM files:

Code:

.THUMB
.ALIGN 2
.THUMB_FUNC

.GLOBAL myFunc

myFunc:
      [... code]
      bx      lr


Then I have the function prototypes in the .h files so that these asm functions can be called from .c code. However, the problem I have here is that when I look at the code in my emulator's disassembler I can see the opcodes are duplicated twice in each 32bits instead of just having the one 16 bit opcode, so it comes up as "<Undefined Opcode>" in the disassembler. However, when I use .ARM code, it works fine (but I obviously want to use THUMB code because it will be faster in ROM).

Basically, I am just really confused as to how most of this stuff works, so if anyone could help me out in any way I would really appreciate it. Thanks!
_________________
- RegularKid

#9602 - regularkid - Sun Aug 10, 2003 5:46 am

Well, i was debugging some more and (by looking at the CPSR) it seems that as soon as the program gets into main() and from then on, it is in ARM mode. So this must mean that I am compiling all my code into ARM code. How would I make it so that all my code is THUMB and only certain code modules (mainly small ASM funcs that are in RAM) are compiled into ARM? Thanks!
_________________
- RegularKid

#9603 - regularkid - Sun Aug 10, 2003 6:31 am

Ok, after searching the forum posts here, I found what I was looking for, but I still am getting some weird errors. So, this is how I beleive I choose whether to compile to ARM or THUMB:

Code:

gcc -marm -mthumb-interwork
gcc -mthumb -mthumb-interwork


I would use one of these depending on which type of code I wanted to compile into. Cool! So, I changed my makefile and made most of my files compile into THUMB, but a few needed to be compiled into ARM. Everything compiles fine, but when it trys to link I get tons of errors saying:

Code:

/cygdrive/c/DEVKIT~1/BIN/../lib/gcc-lib/arm-agb-elf/3.0.2/../../../../arm-agb-elf/bin/ld: Warning: strcmp.o does not support interworking, whereas Game.elf does


I thought that adding the "-mthumb-interwork" would fix the calls between arm/thumb code. Am I missing something here? I will keep searching around for answers, but any help would be very nice. Thanks!
_________________
- RegularKid

#9607 - DekuTree64 - Sun Aug 10, 2003 4:54 pm

Yeah, I was reading this post yesterday and I thought it sounded like it wasn't interworking properly, but then I saw that you had specified -mthumb-interwork so I was stumped and didn't reply. Maybe try moving it from the CC definition to CFLAGS. I don't think it would make any difference, but you never know.
Also, you should compile ASM files with GCC, cause I'm not sure if as runs the preprocessor on it even if it is .S instead of .s. GCC stands for GNU Cross Compiler, not GNU C Compiler (as I once thought^_^), so you just call it for everything and let it decide what to do by the file extension.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#9608 - regularkid - Sun Aug 10, 2003 5:34 pm

hooray! I finally got it working. I'm actually not sure what happened, but I re-downloaded devkitadvance and then after a rebuild all, the linking errors went away! I'm going to keep checking/testing to make sure that everything did infact get compiled correctly, but it seems that everything is good now!
_________________
- RegularKid

#9623 - torne - Mon Aug 11, 2003 11:22 am

The error given previously indicates that it was linking against the non-interworking version of libc. Doing a fresh build should probably fix that (as it did).

DekuTree is right; .S files should be assembled with GCC. If it's working for you using as, then you are presumably not actually using any preprocessor instructions. BTW, GCC stands for GNU Compiler Collection, not cross-compiler. It did *used* to stand for GNU C Compiler.

Torne