RPA Toolkit
Modified the public API of rvm_relocmap_t to add support for multiple relocation...
[rpatk.git] / tests / testmisc / asm-bl.c
1 #include <stdio.h>
2 #include "common.h"
3 #include "rvmcodemap.h"
4 #include "rvmrelocmap.h"
5
6
7         
8 int main(int argc, char *argv[])
9 {
10         ruint ret = 0;
11         ruint off = 0;
12         rvm_asmins_t vmcode[256];
13         rvm_codelabel_t *err = NULL;
14         rvmcpu_t *vm = rvm_cpu_create_default();
15         rvm_codemap_t *codemap = rvm_codemap_create();
16         rvm_relocmap_t *relocmap = rvm_relocmap_create();
17
18         rvm_cpu_addswitable(vm, "common_table", common_calltable);
19
20         rvm_relocmap_add(relocmap, RVM_RELOC_CODE, RVM_RELOC_BRANCH, off, rvm_codemap_lookupadd_s(codemap, "l_main"));
21         vmcode[off++]   = rvm_asm(RVM_B,   DA, XX, XX, 0);
22
23         /*
24          * R0 = R0 + R1
25          */
26         rvm_codemap_addoffset_s(codemap, "l_add2", rvm_codemap_lookupadd_s(codemap, ".code"), RVM_CODE2BYTE_OFFSET(off));
27         vmcode[off++] = rvm_asm(RVM_ADD, R0, R0, R1, 0);
28         vmcode[off++] = rvm_asm(RVM_RET, XX, XX, XX, 0);
29
30
31         /*
32          * R0 = R0 + R1 + R2
33          */
34         rvm_codemap_addoffset_s(codemap, "l_add3", rvm_codemap_lookupadd_s(codemap, ".code"), RVM_CODE2BYTE_OFFSET(off));
35         vmcode[off++] = rvm_asm(RVM_PUSHM,DA, XX, XX, BIT(R7)|BIT(R8)|BIT(SP)|BIT(LR));
36         vmcode[off++] = rvm_asm(RVM_PUSH, R2, XX, XX, 0);
37         rvm_relocmap_add(relocmap, RVM_RELOC_CODE, RVM_RELOC_JUMP, off, rvm_codemap_lookupadd_s(codemap, "l_add2"));
38         vmcode[off++] = rvm_asm(RVM_BXL,   DA, XX, XX, 0);
39         vmcode[off++] = rvm_asm(RVM_POP,  R1, XX, XX, 0);
40         rvm_relocmap_add(relocmap, RVM_RELOC_CODE, RVM_RELOC_JUMP, off, rvm_codemap_lookupadd_s(codemap, "l_add2"));
41         vmcode[off++] = rvm_asm(RVM_BXL,   DA, XX, XX, 0);
42         vmcode[off++] = rvm_asm(RVM_POPM, DA, XX, XX, BIT(R7)|BIT(R8)|BIT(SP)|BIT(LR));
43         vmcode[off++] = rvm_asm(RVM_RET,  XX, XX, XX, 0);
44         /*
45          * We could directly restore the LR in the PC, so we will not need the RET instruction after POPM
46          *
47          * vmcode[off++] = rvm_asm(RVM_POPM, DA, XX, XX, BIT(R7)|BIT(R8)|BIT(SP)|BIT(PC));
48          *
49          */
50
51         rvm_codemap_addoffset_s(codemap, "l_main", rvm_codemap_lookupadd_s(codemap, ".code"), RVM_CODE2BYTE_OFFSET(off));
52         vmcode[off++] = rvm_asm(RVM_MOV, R0, DA, XX, 1);
53         vmcode[off++] = rvm_asm(RVM_MOV, R1, DA, XX, 2);
54         rvm_relocmap_add(relocmap, RVM_RELOC_CODE, RVM_RELOC_JUMP, off, rvm_codemap_lookupadd_s(codemap, "l_add2"));
55         vmcode[off++] = rvm_asm(RVM_BXL,  DA, XX, XX, 0);
56         VMTEST_REG(vmcode, off, 0, 3, "BL/RET");
57         vmcode[off++] = rvm_asm(RVM_MOV, R0, DA, XX, 1);
58         vmcode[off++] = rvm_asm(RVM_MOV, R1, DA, XX, 2);
59         vmcode[off++] = rvm_asm(RVM_MOV, R2, DA, XX, 4);
60         rvm_relocmap_add(relocmap, RVM_RELOC_CODE, RVM_RELOC_JUMP, off, rvm_codemap_lookupadd_s(codemap, "l_add3"));
61         vmcode[off++] = rvm_asm(RVM_BXL,  DA, XX, XX, 0);
62         VMTEST_REG(vmcode, off, 0, 7, "BL/RET");
63         vmcode[off++] = rvm_asm(RVM_EXT, R0, XX, XX, 0);
64
65         rvm_codemap_addpointer_s(codemap, ".code", &vmcode[0]);
66         if (rvm_relocmap_relocate(relocmap, codemap, vmcode, &err) < 0) {
67                 r_printf("Unresolved symbol: %s\n", err->name->str);
68                 goto end;
69         }
70
71 #ifdef EXECDEBUG
72         ret = rvm_cpu_exec_debug(vm, vmcode, 0);
73 #else
74         ret = rvm_cpu_exec(vm, vmcode, 0);
75 #endif
76
77 end:
78         rvm_cpu_destroy(vm);
79         rvm_codemap_destroy(codemap);
80         rvm_relocmap_destroy(relocmap);
81         return 0;
82 }