Skip to content

Commit

Permalink
Merge branch 'feature/aarch-asm'
Browse files Browse the repository at this point in the history
  • Loading branch information
tyfkda committed Jun 13, 2024
2 parents 9c5be8b + 5ec6086 commit bc70c7b
Show file tree
Hide file tree
Showing 18 changed files with 1,510 additions and 73 deletions.
8 changes: 8 additions & 0 deletions include/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,14 @@ typedef struct {
#define R_X86_64_PC32 (2) /* PC relative 32 bit signed */
#define R_X86_64_PLT32 (4) /* 32 bit PLT address */

#define R_AARCH64_ABS64 257
#define R_AARCH64_ADR_PREL_PG_HI21 275
#define R_AARCH64_ADR_PREL_PG_HI21_NC 276
#define R_AARCH64_ADD_ABS_LO12_NC 277
#define R_AARCH64_CALL26 283
#define R_AARCH64_ADR_GOT_PAGE 311
#define R_AARCH64_LD64_GOT_LO12_NC 312

#define R_RISCV_64 (2)
#define R_RISCV_BRANCH (16)
#define R_RISCV_JAL (17)
Expand Down
2 changes: 1 addition & 1 deletion include/math.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ int isinf(double x);
int signbit(double x);
double copysign(double x, double f);

#if defined(__APPLE__) || defined(__GNUC__) || defined(__riscv)
#if defined(__APPLE__) || defined(__GNUC__) || defined(__aarch64__) || defined(__riscv)
// isfinite, isinf and isnan is defined by macro and not included in lib file,
// so it will be link error.
#include <stdint.h>
Expand Down
2 changes: 1 addition & 1 deletion libsrc/crt0/_start.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#pragma GCC diagnostic ignored "-Wunused-function"
#endif

char **environ;
extern char **environ;

#if defined(__linux__)

Expand Down
22 changes: 11 additions & 11 deletions libsrc/misc/longjmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,23 @@ void longjmp(jmp_buf env, int result) {
#define RESTORE_FREGS // Empty
#else
#define RESTORE_FREGS \
"ldp d8, d9, [x0, 112]\n" \
"ldp d10, d11, [x0, 128]\n" \
"ldp d12, d13, [x0, 144]\n" \
"ldp d14, d15, [x0, 160]\n"
"ldp d8, d9, [x0, #112]\n" \
"ldp d10, d11, [x0, #128]\n" \
"ldp d12, d13, [x0, #144]\n" \
"ldp d14, d15, [x0, #160]\n"
#endif
__asm("ldp fp, lr, [x0]\n"
"ldp x9, x19, [x0, 16]\n"
"ldp x20, x21, [x0, 32]\n"
"ldp x22, x23, [x0, 48]\n"
"ldp x24, x25, [x0, 64]\n"
"ldp x26, x27, [x0, 80]\n"
"ldp x28, x29, [x0, 96]\n"
"ldp x9, x19, [x0, #16]\n"
"ldp x20, x21, [x0, #32]\n"
"ldp x22, x23, [x0, #48]\n"
"ldp x24, x25, [x0, #64]\n"
"ldp x26, x27, [x0, #80]\n"
"ldp x28, x29, [x0, #96]\n"
RESTORE_FREGS
"mov sp, x9\n"
"mov w0, w1\n" // Result value.
"cmp w0, wzr\n"
"b.ne .longjmp_0\n"
"bne .longjmp_0\n"
"mov w0, #1\n"
".longjmp_0:");
}
Expand Down
20 changes: 10 additions & 10 deletions libsrc/misc/setjmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,19 @@ int setjmp(jmp_buf env) {
#define SAVE_FREGS // Empty
#else
#define SAVE_FREGS \
"stp d8, d9, [x0, 112]\n" \
"stp d10, d11, [x0, 128]\n" \
"stp d12, d13, [x0, 144]\n" \
"stp d14, d15, [x0, 160]\n"
"stp d8, d9, [x0, #112]\n" \
"stp d10, d11, [x0, #128]\n" \
"stp d12, d13, [x0, #144]\n" \
"stp d14, d15, [x0, #160]\n"
#endif
__asm("stp fp, lr, [x0]\n"
"mov x9, sp\n"
"stp x9, x19, [x0, 16]\n"
"stp x20, x21, [x0, 32]\n"
"stp x22, x23, [x0, 48]\n"
"stp x24, x25, [x0, 64]\n"
"stp x26, x27, [x0, 80]\n"
"stp x28, x29, [x0, 96]\n"
"stp x9, x19, [x0, #16]\n"
"stp x20, x21, [x0, #32]\n"
"stp x22, x23, [x0, #48]\n"
"stp x24, x25, [x0, #64]\n"
"stp x26, x27, [x0, #80]\n"
"stp x28, x29, [x0, #96]\n"
SAVE_FREGS
"mov w0, wzr");
}
Expand Down
1 change: 1 addition & 0 deletions libsrc/stdlib/environ.c
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
char **environ;
2 changes: 1 addition & 1 deletion libsrc/stdlib/getenv.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "stdlib.h"
#include "string.h"

char **environ;
extern char **environ;

char *getenv(const char *varname) {
if (environ != NULL) {
Expand Down
102 changes: 102 additions & 0 deletions src/as/arch/aarch64/aarch64_code.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#pragma once

#define IMM(imm, t, b) (((imm) >> (b)) & ((1 << (t - b + 1)) - 1))

#define W_MOVK(sz, rd, imm, sft) MAKE_CODE32(inst, code, 0x72800000U | ((sz) << 31) | ((sft) << 21) | (((imm) & ((1U << 16) - 1)) << 5) | (rd))
#define W_MOVZ(sz, rd, imm, sft) MAKE_CODE32(inst, code, 0x52800000U | ((sz) << 31) | ((sft) << 21) | (((imm) & ((1U << 16) - 1)) << 5) | (rd))
#define W_MOVN(sz, rd, imm, sft) MAKE_CODE32(inst, code, 0x12800000U | ((sz) << 31) | ((sft) << 21) | (((imm) & ((1U << 16) - 1)) << 5) | (rd))

#define W_ADD_I(sz, rd, rn, imm) MAKE_CODE32(inst, code, 0x11000000U | ((sz) << 31) | (((imm) & ((1U << 12) - 1)) << 10) | ((rn) << 5) | (rd))
#define W_ADD_S(sz, rd, rn, rm, imm) MAKE_CODE32(inst, code, 0x0b000000U | ((sz) << 31) | ((rm) << 16) | (((imm) & ((1U << 6) - 1)) << 10) | ((rn) << 5) | (rd))
#define W_ADD_E(sz, rd, rn, rm, option, ov) MAKE_CODE32(inst, code, 0x4b200000U | ((sz) << 31) | ((rm) << 16) | ((option) << 13) | ((ov) << 10) | ((rn) << 5) | (rd))
#define W_ADDS_I(sz, rd, rn, imm) MAKE_CODE32(inst, code, 0x31000000U | ((sz) << 31) | (((imm) & ((1U << 12) - 1)) << 10) | ((rn) << 5) | (rd))
#define W_ADDS_S(sz, rd, rn, rm, imm) MAKE_CODE32(inst, code, 0x2b000000U | ((sz) << 31) | ((rm) << 16) | (((imm) & ((1U << 6) - 1)) << 10) | ((rn) << 5) | (rd))
#define W_SUB_I(sz, rd, rn, imm) MAKE_CODE32(inst, code, 0x51000000U | ((sz) << 31) | (((imm) & ((1U << 12) - 1)) << 10) | ((rn) << 5) | (rd))
#define W_SUB_S(sz, rd, rn, rm, imm) MAKE_CODE32(inst, code, 0x4b000000U | ((sz) << 31) | ((rm) << 16) | (((imm) & ((1U << 6) - 1)) << 10) | ((rn) << 5) | (rd))
#define W_SUBS_I(sz, rd, rn, imm) MAKE_CODE32(inst, code, 0x71000000U | ((sz) << 31) | (((imm) & ((1U << 12) - 1)) << 10) | ((rn) << 5) | (rd))
#define W_SUBS_S(sz, rd, rn, rm, imm) MAKE_CODE32(inst, code, 0x6b000000U | ((sz) << 31) | ((rm) << 16) | (((imm) & ((1U << 6) - 1)) << 10) | ((rn) << 5) | (rd))
#define W_SUB_E(sz, rd, rn, rm, option, ov) MAKE_CODE32(inst, code, 0x4b200000U | ((sz) << 31) | ((rm) << 16) | ((option) << 13) | ((ov) << 10) | ((rn) << 5) | (rd))
#define W_MADD(sz, rd, rn, rm, ra) MAKE_CODE32(inst, code, 0x1b000000U | ((sz) << 31) | ((rm) << 16) | ((ra) << 10) | ((rn) << 5) | (rd))
#define W_MSUB(sz, rd, rn, rm, ra) MAKE_CODE32(inst, code, 0x1b008000U | ((sz) << 31) | ((rm) << 16) | ((ra) << 10) | ((rn) << 5) | (rd))
#define W_SDIV(sz, rd, rn, rm) MAKE_CODE32(inst, code, 0x1ac00c00U | ((sz) << 31) | ((rm) << 16) | ((rn) << 5) | (rd))
#define W_UDIV(sz, rd, rn, rm) MAKE_CODE32(inst, code, 0x1ac00800U | ((sz) << 31) | ((rm) << 16) | ((rn) << 5) | (rd))
#define W_AND_S(sz, rd, rn, rm, imm) MAKE_CODE32(inst, code, 0x0a000000U | ((sz) << 31) | ((rm) << 16) | (((imm) & ((1U << 6) - 1)) << 10) | ((rn) << 5) | (rd))
#define W_ORR_S(sz, rd, rn, rm, imm) MAKE_CODE32(inst, code, 0x2a000000U | ((sz) << 31) | ((rm) << 16) | (((imm) & ((1U << 6) - 1)) << 10) | ((rn) << 5) | (rd))
#define W_EOR_S(sz, rd, rn, rm, imm) MAKE_CODE32(inst, code, 0x4a000000U | ((sz) << 31) | ((rm) << 16) | (((imm) & ((1U << 6) - 1)) << 10) | ((rn) << 5) | (rd))
#define W_EON_S(sz, rd, rn, rm, imm) MAKE_CODE32(inst, code, 0x4a200000U | ((sz) << 31) | ((rm) << 16) | (((imm) & ((1U << 6) - 1)) << 10) | ((rn) << 5) | (rd))

#define W_LSLV(sz, rd, rn, rm) MAKE_CODE32(inst, code, 0x1ac02000U | ((sz) << 31) | ((rm) << 16) | ((rn) << 5) | (rd))
#define W_LSRV(sz, rd, rn, rm) MAKE_CODE32(inst, code, 0x1ac02400U | ((sz) << 31) | ((rm) << 16) | ((rn) << 5) | (rd))
#define W_ASRV(sz, rd, rn, rm) MAKE_CODE32(inst, code, 0x1ac02800U | ((sz) << 31) | ((rm) << 16) | ((rn) << 5) | (rd))

#define W_SBFM(sz, rd, sn, rn, immr, imms) MAKE_CODE32(inst, code, 0x13000000U | ((sz) << 31) | ((sn) << 22) | ((immr) << 16) | ((imms) << 10) | ((rn) << 5) | (rd))
#define W_UBFM(sz, rd, sn, rn, immr, imms) MAKE_CODE32(inst, code, 0x53000000U | ((sz) << 31) | ((sn) << 22) | ((immr) << 16) | ((imms) << 10) | ((rn) << 5) | (rd))

#define W_LDUR(b, s, rt, ofs, base) MAKE_CODE32(inst, code, 0x38400000U | ((b) << 30) | ((s) << 23) | ((((ofs) & ((1U << 9) - 1))) << 12) | ((base) << 5) | (rt))
#define W_LDR_UIMM(b, s, rt, ofs, base) MAKE_CODE32(inst, code, 0x39400000U | ((b) << 30) | ((s) << 23) | ((((ofs) & ((1U << 12) - 1))) << 10) | ((base) << 5) | (rt))
#define W_LDR(b, s, rt, ofs, base, prepost) MAKE_CODE32(inst, code, 0x38400000U | ((b) << 30) | ((s) << 23) | ((((ofs) & ((1U << 9) - 1))) << 12) | ((prepost) << 10) | ((base) << 5) | (rt))
#define W_STUR(b, rt, ofs, base) MAKE_CODE32(inst, code, 0x38000000U | ((b) << 30) | ((((ofs) & ((1U << 9) - 1))) << 12) | ((base) << 5) | (rt))
#define W_STR_UIMM(b, rt, ofs, base) MAKE_CODE32(inst, code, 0x39000000U | ((b) << 30) | ((((ofs) & ((1U << 12) - 1))) << 10) | ((base) << 5) | (rt))
#define W_STR(b, rt, ofs, base, prepost) MAKE_CODE32(inst, code, 0x38000000U | ((b) << 30) | ((((ofs) & ((1U << 9) - 1))) << 12) | ((prepost) << 10) | ((base) << 5) | (rt))
#define W_LDP(sz, rs1, rs2, ofs, base, prepost) MAKE_CODE32(inst, code, 0x28400000U | ((sz) << 31) | ((prepost) << 23) | (((((ofs) >> 3) & ((1U << 7) - 1))) << 15) | ((rs2) << 10) | ((base) << 5) | (rs1))
#define W_STP(sz, rs1, rs2, ofs, base, prepost) MAKE_CODE32(inst, code, 0x28000000U | ((sz) << 31) | ((prepost) << 23) | (((((ofs) >> 3) & ((1U << 7) - 1))) << 15) | ((rs2) << 10) | ((base) << 5) | (rs1))

#define W_LDR_R(sz, rt, base, rm, sz2, s, option) MAKE_CODE32(inst, code, 0xb8600800U | ((sz) << 30) | ((rm) << 16) | ((option) << 13) | ((s) << 12) | ((base) << 5) | (rt))
#define W_LDRB_R(rt, base, rm, option) MAKE_CODE32(inst, code, 0x38400000U | ((((ofs) & ((1U << 9) - 1))) << 12) | ((option) << 10) | ((base) << 5) | (rt))
#define W_LDRSB_R(rt, base, rm, option) MAKE_CODE32(inst, code, 0x38c00000U | ((((ofs) & ((1U << 9) - 1))) << 12) | ((option) << 10) | ((base) << 5) | (rt))
#define W_LDRH_R(rt, base, rm, option) MAKE_CODE32(inst, code, 0x78400000U | ((((ofs) & ((1U << 9) - 1))) << 12) | ((option) << 10) | ((base) << 5) | (rt))
#define W_LDRSH_R(rt, base, rm, option) MAKE_CODE32(inst, code, 0x78c00000U | ((((ofs) & ((1U << 9) - 1))) << 12) | ((option) << 10) | ((base) << 5) | (rt))
#define W_STR_R(sz, rt, base, rm, option) MAKE_CODE32(inst, code, 0xb8200800U | ((sz) << 30) | ((rm) << 16) | ((option) << 13) | ((base) << 5) | (rt))
#define W_STRB_R(rt, base, rm, option) MAKE_CODE32(inst, code, 0x38000000U | ((((ofs) & ((1U << 9) - 1))) << 12) | ((option) << 10) | ((base) << 5) | (rt))
#define W_STRH_R(rt, base, rm, option) MAKE_CODE32(inst, code, 0x78000000U | ((((ofs) & ((1U << 9) - 1))) << 12) | ((option) << 10) | ((base) << 5) | (rt))

#define W_ADRP(rd, imm) MAKE_CODE32(inst, code, 0x90000000U | (IMM(imm, 31, 30) << 29) | (IMM(imm, 29, 12) << 5) | (rd))

#define W_CSINC(sz, rd, rn, rm, cond) MAKE_CODE32(inst, code, 0x1a800400U | ((sz) << 31) | ((rm) << 16) | ((cond) << 12) | ((rn) << 5) | (rd))

#define W_B() MAKE_CODE32(inst, code, 0x14000000U)
#define W_BR(rn) MAKE_CODE32(inst, code, 0xd61f0000U | ((rn) << 5))
#define W_BCC(cond) MAKE_CODE32(inst, code, 0x54000000U | (cond))

#define W_BL(offset) MAKE_CODE32(inst, code, 0x94000000U | ((offset) & ((1U << 26) - 1)))
#define W_BLR(rn) MAKE_CODE32(inst, code, 0xd63f0000U | ((rn) << 5))
#define W_RET(rn) MAKE_CODE32(inst, code, 0xd65f0000U | ((rn) << 5))
#define W_SVC(imm) MAKE_CODE32(inst, code, 0xd4000001U | ((imm) << 5))

#define P_MOV(sz, rd, rs) W_ORR_S(sz, rd, ZERO, rs, 0)
#define P_MOV_SP(sz, rd, rs) W_ADD_I(sz, rd, rs, 0)
#define P_MUL(sz, rd, rn, rm) W_MADD(sz, rd, rn, rm, ZERO)
#define P_CMP(sz, rm, rn) W_SUBS_S(sz, ZERO, rm, rn, 0)
#define P_CMP_I(sz, rd, imm) W_SUBS_I(sz, ZERO, rd, imm)
#define P_CMN(sz, rn, rm) W_ADDS_S(sz, ZERO, rn, rm, 0)
#define P_CMN_I(sz, rd, imm) W_ADDS_I(sz, ZERO, rd, imm)
#define P_LSL_I(sz, rd, rn, imm) W_UBFM(sz, opr1->reg.no, sz, opr2->reg.no, -(imm) & (63>>(1-(sz))), (63>>(1-(sz))) - (imm))
#define P_LSR_I(sz, rd, rn, imm) W_UBFM(sz, opr1->reg.no, sz, opr2->reg.no, imm, 63>>(1-(sz)))
#define P_ASR_I(sz, rd, rn, imm) W_SBFM(sz, opr1->reg.no, sz, opr2->reg.no, imm, 63>>(1-(sz)))
#define P_CSET(sz, rd, cond) W_CSINC(sz, rd, ZERO, ZERO, (cond) ^ 1)

// FP instructions.

#define F_LDUR(b, s, rt, ofs, base) MAKE_CODE32(inst, code, 0xbc400000U | ((b) << 30) | ((s) << 23) | ((((ofs) & ((1U << 9) - 1))) << 12) | ((base) << 5) | (rt))
#define F_LDR_UIMM(b, s, rt, ofs, base) MAKE_CODE32(inst, code, 0xbd400000U | ((b) << 30) | ((s) << 23) | ((((ofs) & ((1U << 12) - 1))) << 10) | ((base) << 5) | (rt))
#define F_LDR(b, s, rt, ofs, base, prepost) MAKE_CODE32(inst, code, 0xbc400000U | ((b) << 30) | ((s) << 23) | ((((ofs) & ((1U << 9) - 1))) << 12) | ((prepost) << 10) | ((base) << 5) | (rt))
#define F_STUR(b, rt, ofs, base) MAKE_CODE32(inst, code, 0xbc000000U | ((b) << 30) | ((((ofs) & ((1U << 9) - 1))) << 12) | ((base) << 5) | (rt))
#define F_STR_UIMM(b, rt, ofs, base) MAKE_CODE32(inst, code, 0xbd000000U | ((b) << 30) | ((((ofs) & ((1U << 12) - 1))) << 10) | ((base) << 5) | (rt))
#define F_STR(b, rt, ofs, base, prepost) MAKE_CODE32(inst, code, 0xbc000000U | ((b) << 30) | ((((ofs) & ((1U << 9) - 1))) << 12) | ((prepost) << 10) | ((base) << 5) | (rt))
#define F_LDP(b, rt, ru, base, ofs, prepost) MAKE_CODE32(inst, code, 0x2c400000U | ((b) << 30) | ((prepost) << 23) | ((((ofs) & ((1U << 10) - (1 << 3)))) << (15 - 3)) | ((ru) << 10) | ((base) << 5) | (rt))
#define F_STP(b, rt, ru, base, ofs, prepost) MAKE_CODE32(inst, code, 0x2c000000U | ((b) << 30) | ((prepost) << 23) | ((((ofs) & ((1U << 10) - (1 << 3)))) << (15 - 3)) | ((ru) << 10) | ((base) << 5) | (rt))

#define FMOV(sz, rd, rn) MAKE_CODE32(inst, code, 0x1e204000U | ((sz) << 22) | ((rn) << 5) | (rd))
#define FADD(sz, rd, rn, rm) MAKE_CODE32(inst, code, 0x1e202800U | ((sz) << 22) | ((rm) << 16) | ((rn) << 5) | (rd))
#define FSUB(sz, rd, rn, rm) MAKE_CODE32(inst, code, 0x1e203800U | ((sz) << 22) | ((rm) << 16) | ((rn) << 5) | (rd))
#define FMUL(sz, rd, rn, rm) MAKE_CODE32(inst, code, 0x1e200800U | ((sz) << 22) | ((rm) << 16) | ((rn) << 5) | (rd))
#define FDIV(sz, rd, rn, rm) MAKE_CODE32(inst, code, 0x1e201800U | ((sz) << 22) | ((rm) << 16) | ((rn) << 5) | (rd))
#define FCMP(sz, rd, rn) MAKE_CODE32(inst, code, 0x1e602000U | ((sz) << 22) | ((rn) << 16) | ((rd) << 5))
#define FNEG(sz, rd, rn) MAKE_CODE32(inst, code, 0x1e214000U | ((sz) << 22) | ((rn) << 5) | (rd))
#define FSQRT(sz, rd, rn) MAKE_CODE32(inst, code, 0x1e21c000U | ((sz) << 22) | ((rn) << 5) | (rd))

#define SCVTF(dsz, rt, ssz, rn) MAKE_CODE32(inst, code, 0x1e220000 | ((dsz) << 31) | ((ssz) << 22) | ((rn) << 5) | (rt))
#define UCVTF(dsz, rt, ssz, rn) MAKE_CODE32(inst, code, 0x1e230000 | ((dsz) << 31) | ((ssz) << 22) | ((rn) << 5) | (rt))
#define FCVT(dsz, rt, rn) MAKE_CODE32(inst, code, 0x1e224000 | ((1 - (dsz)) << 22) | ((dsz) << 15) | ((rn) << 5) | (rt))
#define FCVTZS(dsz, rt, ssz, rn) MAKE_CODE32(inst, code, 0x1e380000 | ((dsz) << 31) | ((ssz) << 22) | ((rn) << 5) | (rt))
#define FCVTZU(dsz, rt, ssz, rn) MAKE_CODE32(inst, code, 0x1e390000 | ((dsz) << 31) | ((ssz) << 22) | ((rn) << 5) | (rt))
Loading

0 comments on commit bc70c7b

Please sign in to comment.