'newlib'에 해당되는 글 2건

  1. 2010.01.03 [MIPS] Assembler 코드 살펴보기 - 4
  2. 2009.12.17 [MIPS] OSX에서 MIPS C Compiler를 빌드하기
Embedded2010. 1. 3. 07:59
이번에는  Loop문이 어떻게 바뀌는지에 대해서 살펴 봅니다.
예제를 새로 짜는 것 보다는 기존에 있던것을 가지고 한번 해보겠습니다.

아래는 NEWLIB 라이브러리에 있는 memset 함수입니다.
참고로, newlib은 c에서 사용하는 여러가지 라이브러리를 embedded  등에서 사용할 수 있도록 제공해주는 라이브러리입니다. 다양한 프로세서에 포팅되어 있습니다. 대부분의 함수가 C로 코딩되어 있지만, 속도가 필요한 부분이나 프로세서에 종속적인 부분에 대해서는 assembler로 되어 있습니다.

주어진 어드레스 m에서 시작해서 주어진 값 c를   n개의 메모리에 차례로 기록하는 것입니다.

........
#define PREFER_SIZE_OVER_SPEED 1
_PTR
_DEFUN (memset, (m, c, n),
        _PTR m _AND
        int c _AND
        size_t n)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) || defined(__mips16)
  char *s = (char *) m;

  while (n-- != 0)
    {
      *s++ = (char) c;
    }

  return m;
#else
  char *s = (char *) m;
  int i;
  unsigned wordtype buffer;
......

#ifdef -else에서 #else는 복잡한(?) 판단문을 가지고 있으므로 위의 #ifdef를 이용하기로 합니다.
그래서 PERFER_SIZE_OF_SPEED를 Define하여서 #ifdef로 컴파일 되게 합니다.

코드를 보면 S라고 하는 스타팅 어드레스는 주어진 인자 m으로 세팅됩니다.
이후 while에서 n을 하나씩 밑으로 카운트 하면서 주어진 인자 c를  S포인터에 기록합니다.
이후 S 포인터를 하나씩 증가시킵니다.


컴파일 커맨드는 아래와 같습니다.
mips-elf-gcc -S -O2 memset.c -o memset.s

컴파일 결과는 아래와 같습니다.

        .file   1 "memset.c"
        .section .mdebug.abi32
        .previous
        .gnu_attribute 4, 1
        .text
        .align  2
        .globl  memset
        .set    nomips16
        .ent    memset
        .type   memset, @function
memset:
        .frame  $sp,0,$31               # vars= 0, regs= 0/0, args= 0, gp= 0
        .mask   0x00000000,0
        .fmask  0x00000000,0
        .set    noreorder
        .set    nomacro

        beq     $6,$0,$L7
        move    $2,$4

        sll     $5,$5,24
        sra     $5,$5,24
        move    $3,$4
$L3:
        addiu   $6,$6,-1
        sb      $5,0($3)
        bne     $6,$0,$L3
        addiu   $3,$3,1

$L7:
        j       $31
        nop

        .set    macro
        .set    reorder
        .end    memset
        .size   memset, .-memset
        .ident  "GCC: (GNU) 4.4.2"

위에서 보면 우선 $6이 $0과 같으면 $L7으로 분기하도록 되어 있습니다.
$0는 0 레지스터 값이므로 항상 0을 가집니다. 즉 주어진 카운트 값이 0이면 더이상 할 필요가 없으므로, 그냥 일을 마치고 돌아가는 것입니다.

따라서 $6이 인자 c (count)에 해당된다는 것을 알수 있습니다.

그리고 그 밑에

        sll     $5,$5,24
        sra     $5,$5,24

구분은 쉬프트 구문인데 $5를 왼쪽으로 24번 보냈다가 오른쪽으로 다시 24번 보내는 구문입니다.
뻉뻉이 돌리는 것인데요, 이렇게 하면 상위 24비트는 모두 0가 됩니다. 위의 구문은 그냥

and $5 , $5 , 0xFF와 같은 구문이 됩니다.

이렇게 해서 하위 8비트 즉 하위 1Byte만 사용한다는 것입니다. 인자 리스트를 쭈욱 보면 c에 해당하는 것이
함수 중간에서 char로 사용하고 있으므로 $5는 c에 해당하는 것임을 눈치밥으로 알수 있습니다.

      .......
      *s++ = (char) c; <-- 요기서  c가 char로 쓰이므로 불필요한 상위 24비트를 날려버리는 것이빈다.
      ....

이렇게 해서 필요한 / 사용할 데이터 타입과 변수들을 정리해 두고 whil에 해당하는 루프를 시작합니다.


$L3:
        addiu   $6,$6,-1
        sb      $5,0($3)
        bne     $6,$0,$L3
        addiu   $3,$3,1

을 살펴 봅니다.
$6이 카운트 값이라고 하였으니 addiu   $6,$6,-1  구문은 자연스럽게
 ...
 while (n-- != 0)
  ...
에서 n--에 해당함을 알 수 있습니다.
이제 갑자기 나온 레지스터 $3 이 보이는데 코드를 보면 레지스터 $5의 값을 어드레스 $3에 기록하는 것을 알 수 있습니다. 즉 메모리에 쓰는 어드레스를 $3에 기록합니다. 따라서 C코드에서 변수 s에 해당하는 것이 $3임을 알수 있습니다.

이후 카운트 값 레지스터 $6이 0이 아니면 계속 루프를 돌고 0이면 밑으로 내려가도록 되어 있습니다.
addiu $3,$3,1 은
어드레스를 1 증가시키는 것에 해당합니다.

      *s++ = (char) c;

에서 s++에 해당합니다.

이는 loop를 돌때 마다 해야 하므로 branch delay slot에 해당하는  BNE다음 구문으로 집어 넣습니다.

이렇게 해서 loop를 돌고 끝나면 jump로 복귀하게 됩니다.
복귀 문인 j 문 다음에 있는 NOP는 그냥 Delay Slot을 사용하지 않도록 하기 위해서 0으로 넣어버린 것입니다.






Posted by GUNDAM_IM
ASIC SoC2009. 12. 17. 13:17
오래간만의 컴파일러 빌드입니다.

1) binutils  설치하기


우선 binutils를 다운 받습니다.
커맨드는 아래와 같습니다.

cvs -z 9 -d :pserver:anoncvs@sourceware.org:/cvs/src login
{enter "anoncvs" as the password}
cvs -z 9 -d :pserver:anoncvs@sourceware.org:/cvs/src co binutils
  

빌드는 아래와 같이 합니다.

mkdir build
cd build
 ../binutils-2.20/configure  --target=mips-elf --prefix=/Volumes/ZGUNDAM/usr/lcao --with-gnu-as --with-gnu-ld
make all
make install

설치가 끝나고 확인하면 아래와 같습니다.

GUNDAMMACPRO:build kevinIm$ ls /Volumes/ZGUNDAM/usr/local/bin/
mips-elf-addr2line      mips-elf-ld             mips-elf-ranlib         mips-elf-strip
mips-elf-ar             mips-elf-nm             mips-elf-readelf
mips-elf-as             mips-elf-objcopy        mips-elf-size
mips-elf-c++filt        mips-elf-objdump        mips-elf-strings

패스가 추가되어야 하기 때문에

export PATH=$PATH:/Volumes/ZGUNDAM/usr/local/bin

으로 미리 추가해 둡니다.

2. gcc를 빌드하기



에서 gcc 최신 버전을 다운 받습니다. 이 글을 쓰는 시점에서는 4.4.2입니다.

다운받아서 압축을 풀고 빌드를 합니다.

mkdir build
cd build
../gcc-4.4.2/configure --target=mips-elf --without-headers --with-gnu-as --with-gnu-ld --disable-shared --prefix=/Volumes/ZGUNDAM/usr/local/ --with-newlib --disable-libssp

그러면 아래와 같은 오류가 발생합니다.

....
checking for correct version of gmp.h... no
configure: error: Building GCC requires GMP 4.1+ and MPFR 2.3.2+.
Try the --with-gmp and/or --with-mpfr options to specify their locations.
Copies of these libraries' source code can be found at their respective
hosting sites as well as at ftp://gcc.gnu.org/pub/gcc/infrastructure/.
.......

GMP 4.1과 MPFR2.32 이상 버전이 필요하다는 의미입니다.
MAC에서는 소스를 가지고 와서 빌드하는 것과 fink등을 이용해서 다운 받는것이 가능합니다.
여기선 그냥 다운 받는것으로 하고 진행합니다.

sudo port install gmp
--->  Fetching gmp
--->  Attempting to fetch gmp-4.3.1.tar.bz2 from ftp://ftp.dti.ad.jp/pub/GNU/gmp
--->  Verifying checksum(s) for gmp
--->  Extracting gmp
--->  Applying patches to gmp
--->  Configuring gmp
--->  Building gmp
--->  Staging gmp into destroot
--->  Installing gmp @4.3.1_1
--->  Activating gmp @4.3.1_1
--->  Cleaning gmp

GUNDAMMACPRO:build kevinIm$ sudo port install mpfr
--->  Fetching lzmautils
--->  Attempting to fetch lzma-4.32.7.tar.gz from http://distfiles.macports.org/lzmautils
--->  Verifying checksum(s) for lzmautils
--->  Extracting lzmautils
--->  Configuring lzmautils
--->  Building lzmautils
--->  Staging lzmautils into destroot
--->  Installing lzmautils @4.32.7_1
--->  Activating lzmautils @4.32.7_1
--->  Cleaning lzmautils
--->  Fetching mpfr
--->  Attempting to fetch patch01 from http://distfiles.macports.org/mpfr/2.4.1
--->  Attempting to fetch patch02 from http://distfiles.macports.org/mpfr/2.4.1
--->  Attempting to fetch patch03 from http://distfiles.macports.org/mpfr/2.4.1
--->  Attempting to fetch patch04 from http://distfiles.macports.org/mpfr/2.4.1
--->  Attempting to fetch mpfr-2.4.1.tar.lzma from http://distfiles.macports.org/mpfr/2.4.1
--->  Verifying checksum(s) for mpfr
--->  Extracting mpfr
--->  Applying patches to mpfr
--->  Configuring mpfr
--->  Building mpfr
--->  Staging mpfr into destroot
--->  Installing mpfr @2.4.1-p4_1
--->  Activating mpfr @2.4.1-p4_1
--->  Cleaning mpfr


그러면 설치가 된다. 설치된 위치는 /opt/local입니다.
이 위치를 반영하여서 다시 아래와 같이 커맨드를 넣습니다.

GUNDAMMACPRO:build kevinIm$ ../gcc-4.4.2/configure --target=mips-elf --without-headers --with-gnu-as --with-gnu-ld --disable-shared --prefix=/Volumes/ZGUNDAM/usr/local/ --with-newlib --disable-libssp --with-gmp=/opt/local --with-mpfr=/opt/local  --enable-languages="c"

make all

그러면 한참 컴파일을 합니다.

그러다가 다음과 같은 오류를 냅니다.

gcc  -g -O2 -DIN_GCC -DCROSS_DIRECTORY_STRUCTURE  -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wcast-qual -Wold-style-definition -Wmissing-format-attribute   -DHAVE_CONFIG_H  -o cc1-dummy c-lang.o stub-objc.o attribs.o c-errors.o c-lex.o c-pragma.o c-decl.o c-typeck.o c-convert.o c-aux-info.o c-common.o c-opts.o c-format.o c-semantics.o c-ppoutput.o c-cppbuiltin.o c-objc-common.o c-dump.o c-pch.o c-parser.o  c-gimplify.o tree-mudflap.o c-pretty-print.o c-omp.o dummy-checksum.o \
          main.o  libbackend.a ../libcpp/libcpp.a ../libdecnumber/libdecnumber.a ../libcpp/libcpp.a ./../intl/libintl.a -liconv  ../libiberty/libiberty.a ../libdecnumber/libdecnumber.a   -L/opt/local/lib -L/opt/local/lib -lmpfr -lgmp
Undefined symbols:
  "_iconv_close", referenced from:
      __cpp_destroy_iconv in libcpp.a(charset.o)
      __cpp_destroy_iconv in libcpp.a(charset.o)
      __cpp_convert_input in libcpp.a(charset.o)
      __nl_free_domain_conv in libintl.a(loadmsgcat.o)
  "_iconv", referenced from:
      _convert_using_iconv in libcpp.a(charset.o)
      _convert_using_iconv in libcpp.a(charset.o)
......


이 오류는 다음과 같이 커맨드를 넣어서 해결한다.

sudo port deactivate libiconv
/sw/bin/fink update libgettext3-dev

이후에 make를 하면 잘 진행된다.

make all
make install

테스트를 하면

GUNDAMMACPRO:build kevinIm$ mips-elf-gcc --help
Usage: mips-elf-gcc [options] file...
Options:
  -pass-exit-codes         Exit with highest error code from a phase
  --help                   Display this information
  --target-help            Display target specific command line options
  --help={target|optimizers|warnings|params|[^]{joined|separate|undocumented}}[,...]
                           Display specific types of command line options
  (Use '-v --help' to display command line options of sub-processes)
  --version                Display compiler version information
  -dumpspecs               Display all of the built in spec strings
  -dumpversion             Display the version of the compiler
  -dumpmachine             Display the compiler's target processor
  -print-search-dirs       Display the directories in the compiler's search path
  -print-libgcc-file-name  Display the name of the compiler's companion library
  -print-file-name=<lib>   Display the full path to library <lib>
  -print-prog-name=<prog>  Display the full path to compiler component <prog>
  -print-multi-directory   Display the root directory for versions of libgcc
.......

3) Newlib 컴파일 하기

다운로드는 다음 커맨드로 받습니다.
  cvs -z 9 -d :pserver:anoncvs@sources.redhat.com:/cvs/src login
  {enter "anoncvs" as the password}
  cvs -z 9 -d :pserver:anoncvs@sources.redhat.com:/cvs/src co newlib

../src/configure --target=mips-elf -prefix=/Volumes/ZGUNDAM/usr/local --with-gnu-as --with-gnu-ld

이후에

make all
make install

을 하면 됩니다.


확인은 아래와 같이 합니다.
GUNDAMMACPRO:build kevinIm$ ls /Volumes/ZGUNDAM/usr/local/mips-elf/lib/

cfe.ld          ddb.ld          ldscripts       libidt.a        libnullmon.a    pcrt0.o
crt0.o          el              libc.a          liblsi.a        libpmon.a       pmon.ld
crt0_cfe.o      idt.ld          libcfe.a        libm.a          lsi.ld          soft-float
ddb-kseg0.ld    idtecoff.ld     libg.a          libnosys.a      nullmon.ld
GUNDAMMACPRO:build kevinIm$



 

'ASIC SoC' 카테고리의 다른 글

Sound Effect Processor  (0) 2010.02.01
[SC] Structure  (0) 2010.01.18
PERL TIP  (0) 2009.12.05
Timing Chart  (0) 2009.11.08
SystemC에서 main() 함수 넣기  (0) 2009.11.04
Posted by GUNDAM_IM