計畫網站:

$ git clone https://code.google.com/p/mips-script/
$ cd script
$ ./mips-universal.sh $INSTALL

host/build 為 x86,target 為 mips。MIPS ABI 主要為底下幾種:

  1. o32: -mabi=32
  2. n32: 因為 n64 指標會導致代碼膨脹,所以發展 n32 ABI。-mabi=n32
  3. n64: SGI 替 64 bit 設計的 ABI。-mabi=64

編譯交叉工具鏈一般需要下載底下檔案:

  1. Linux
  2. binutils
  3. GCC
  4. glibc
  5. gdb (optional)

編譯交叉工具鏈流程如下:

  1. 編譯並安裝 binutils。
    $ ../binutils-2.22/configure \
      --disable-nls
    • –disable-nls 禁用 Native Language Support (NLS) 支援, 僅用英文輸出。
  2. 安裝 Linux 頭文件。
  3. 用本地 gcc 編譯出第一階段 (stage 1,或稱 bootstrap) 的 GCC,此階段僅編譯 gcc 編譯器,不包含其它支援函式庫,如 libgcc。此次所得編譯器僅能編譯出目的碼,並不能編譯出執行檔,這是因為缺少目標平台 C 函式庫的緣故。
    $ ../gcc-4.7.1/configure \
      --without-headers --with-newlib
    $ make install-gcc
    • –without-headers 告訴 GCC 此次編譯不依賴目標平台上的任何 C 函式庫中的頭文件,因為此次僅編譯 gcc 編譯器,不包含其它支援函式庫,如 libgcc
    • –with-newlib 告訴 GCC 此次編譯不依賴目標平台上的任何 C 函式庫,因為此次僅編譯 gcc 編譯器,不包含其它支援函式庫,如 libgcc
  4. 用第一階段 gcc 編譯目標平台所用的 C 函式庫,如: glibc。在此之前,你沒有任何目標平台 C 函式庫可用。
    $ ../glibc-2.16.0/configure \
      --with-headers=${SYSROOT}/usr/include
  5. 用第一階段 gcc 和其編譯所得的 glibc 編譯第二階段的 GCC,包含 gcc 編譯器和其它支援函式庫,如 libgcc
  6. 編譯 gdb

LLVM

$ clang -ccc-gcc-name mips-unknown-linux-gnu-gcc -ccc-host-triple mips-unknown-linux-gnueabi -c test.c \
  -emit-llvm -o test.bc
$ llc test.bc
$ mips64el-unknown-linux-gnu-gcc -static -mabi=32 test.s
$ qemu-mipsel a.out

QEMU

  1. 拷貝一份鏡像,並建立分支。
    $ git clone git@github.com:azru0512/qemu-mips-microdsp.git
    $ git checkout -b dsp
    $ git checkout -b dsp-wip
    # git push origin/dsp-wip
    $ git push --all
    # 在 dsp-wip (work in progress) 工作。
    $ git clone git@github.com:azru0512/qemu-mips-microdsp.git -b dsp-wip
    $ cd build
    $ ../qemu-mips-microdsp/configure --target-list=mips-softmmu,mips-linux-user
  2. 撰寫測試並編譯。
    $ git clone git://github.com/J-Liu/Cross-SDK.git
    $ ./bin/mips-linux-gnu-gcc -mmicromips -S ../test.c
diff --git a/target-mips/translate.c b/target-mips/translate.c
index f6fc0c2..42bd66e 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -10355,6 +10355,8 @@ enum {
     INS = 0x0c,
     EXT = 0x2c,
     POOL32AXF = 0x3c
+
+    /* DSP */
 };
 
 /* POOL32AXF encoding of minor opcode field extension */
@@ -10452,6 +10454,8 @@ enum {
     MFLO32 = 0x1,
     MTHI32 = 0x2,
     MTLO32 = 0x3,
+
+    /* DSP */
 };
 
 /* POOL32B encoding of minor opcode field (bits 15..12) */
/* POOL32A encoding of minor opcode field */
 
enum {
    /* These opcodes are distinguished only by bits 9..6; those bits are
     * what are recorded below. */
    SLL32 = 0x0,
    SRL32 = 0x1,
    SRA = 0x2,
    ROTR = 0x3,
 
    ... 略 ...
 
}
 
/* POOL32AXF encoding of minor opcode field extension */
 
enum {
    /* bits 11..6 */
    TEQ = 0x00,
    TGE = 0x08,
    TGEU = 0x10,
    TLT = 0x20,
    TLTU = 0x28,
    TNE = 0x30,
 
    MFC0 = 0x03,
    MTC0 = 0x0b,
 
    /* bits 13..12 for 0x01 */
    MFHI_ACC = 0x0,
    MFLO_ACC = 0x1,
    MTHI_ACC = 0x2,
    MTLO_ACC = 0x3,
 
 
    ... 略 ...
 
}
 
static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
                                    uint16_t insn_hw1, int *is_branch)
{
    ... 略 ...
 
    //31..26 位
    op = (ctx->opcode >> 26) & 0x3f;
    switch (op) {
    case POOL32A:
        //5..0 位
        minor = ctx->opcode & 0x3f;
        switch (minor) {
        case 0x00:
            //9..6 位
            minor = (ctx->opcode >> 6) & 0xf;
 
            ... 略 ...
 
        case 0x10:
 
            ... 略 ...
 
        }
    }
}
 
static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
                           int *is_branch)
{
    int extension = (ctx->opcode >> 6) & 0x3f;
    int minor = (ctx->opcode >> 12) & 0xf;
    uint32_t mips32_op;
 
    switch (extension) {
 
    ... 略 ...
}

外部連結

登录