1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 03:40:34 +02:00

Merge remote-tracking branch 'lightening/master'

This commit is contained in:
Andy Wingo 2019-05-27 11:34:39 +02:00
commit 803e412f53
6 changed files with 286 additions and 12 deletions

View file

@ -477,6 +477,11 @@ jit_load_args_3(jit_state_t *_jit, jit_operand_t a, jit_operand_t b,
M(_FGo_, ldxi_f) \
M(_FGG_, ldxr_d) \
M(_FGo_, ldxi_d) \
\
M(_GG__, ldr_atomic) \
M(_GG__, str_atomic) \
M(_GGG_, swap_atomic) \
M(_GGGG, cas_atomic) \
\
M(_GG__, str_c) \
M(_pG__, sti_c) \

View file

@ -221,6 +221,10 @@ oxxrs(jit_state_t *_jit, int32_t Op,
#define A64_MUL 0x1b007c00
#define A64_SMULH 0x9b407c00
#define A64_UMULH 0x9bc07c00
#define A64_LDAR 0xc8dffc00
#define A64_STLR 0xc89ffc00
#define A64_LDAXR 0xc85ffc00
#define A64_STLXR 0xc800fc00
#define A64_STRBI 0x39000000
#define A64_LDRBI 0x39400000
#define A64_LDRSBI 0x39800000
@ -646,6 +650,30 @@ REV(jit_state_t *_jit, int32_t Rd, int32_t Rn)
return o_xx(_jit, A64_REV,Rd,Rn);
}
static void
LDAR(jit_state_t *_jit, int32_t Rt, int32_t Rn)
{
return o_xx(_jit, A64_LDAR, Rt, Rn);
}
static void
STLR(jit_state_t *_jit, int32_t Rt, int32_t Rn)
{
return o_xx(_jit, A64_STLR, Rt, Rn);
}
static void
LDAXR(jit_state_t *_jit, int32_t Rt, int32_t Rn)
{
return o_xx(_jit, A64_LDAXR, Rt, Rn);
}
static void
STLXR(jit_state_t *_jit, int32_t Rt, int32_t Rn, int32_t Rm)
{
return oxxx(_jit, A64_STLXR, Rt, Rn, Rm);
}
static void
LDRSB(jit_state_t *_jit, int32_t Rt, int32_t Rn, int32_t Rm)
{
@ -2465,3 +2493,50 @@ patch_jmp_without_veneer(jit_state_t *_jit, uint32_t *loc)
{
patch_jmp_offset(loc, _jit->pc.ui - loc);
}
static void
ldr_atomic(jit_state_t *_jit, int32_t dst, int32_t loc)
{
LDAR(_jit, dst, loc);
}
static void
str_atomic(jit_state_t *_jit, int32_t loc, int32_t val)
{
STLR(_jit, val, loc);
}
static void
swap_atomic(jit_state_t *_jit, int32_t dst, int32_t loc, int32_t val)
{
void *retry = jit_address(_jit);
int32_t result = jit_gpr_regno(get_temp_gpr(_jit));
int32_t val_or_tmp = dst == val ? jit_gpr_regno(get_temp_gpr(_jit)) : val;
movr(_jit, val_or_tmp, val);
LDAXR(_jit, dst, loc);
STLXR(_jit, val_or_tmp, loc, result);
jit_patch_there(_jit, bnei(_jit, result, 0), retry);
if (dst == val) unget_temp_gpr(_jit);
unget_temp_gpr(_jit);
}
static void
cas_atomic(jit_state_t *_jit, int32_t dst, int32_t loc, int32_t expected,
int32_t desired)
{
int32_t dst_or_tmp;
if (dst == loc || dst == expected || dst == expected)
dst_or_tmp = jit_gpr_regno(get_temp_gpr(_jit));
else
dst_or_tmp = dst;
void *retry = jit_address(_jit);
LDAXR(_jit, dst_or_tmp, loc);
jit_reloc_t bad = bner(_jit, dst_or_tmp, expected);
int result = jit_gpr_regno(get_temp_gpr(_jit));
STLXR(_jit, desired, loc, result);
jit_patch_there(_jit, bnei(_jit, result, 0), retry);
unget_temp_gpr(_jit);
jit_patch_here(_jit, bad);
movr(_jit, dst, dst_or_tmp);
unget_temp_gpr(_jit);
}

View file

@ -179,6 +179,9 @@
#define THUMB2_STRI 0xf8400c00
#define THUMB2_LDM_W 0x00200000
#define THUMB2_PUSH 0xe92d0000
#define THUMB_DMB 0xf3bf8f50
#define THUMB_LDREX 0xe8500f00
#define THUMB_STREX 0xe8400000
#define _NOREG (jit_gpr_regno(_PC))
@ -1030,6 +1033,26 @@ T2_BLXI(jit_state_t *_jit)
return tb(_jit, THUMB2_BLXI);
}
enum dmb_option { DMB_ISH = 0xb };
static void
T1_DMB(jit_state_t *_jit, enum dmb_option option)
{
emit_wide_thumb(_jit, THUMB_DMB|_u4(option));
}
static void
T1_LDREX(jit_state_t *_jit, int32_t rt, int32_t rn, int8_t offset)
{
emit_wide_thumb(_jit, THUMB_LDREX|(_u4(rn)<<16)|(_u4(rt)<<12)|_u8(offset));
}
static void
T1_STREX(jit_state_t *_jit, int32_t rd, int32_t rt, int32_t rn, int8_t offset)
{
emit_wide_thumb
(_jit, THUMB_STREX|(_u4(rn)<<16)|(_u4(rt)<<12)|(_u4(rd)<<8)|_u8(offset));
}
static void
T1_LDRSB(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t rm)
{
@ -1171,7 +1194,7 @@ T1_LDR(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t rm)
static void
T2_LDR(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t rm)
{
return torxr(_jit, THUMB2_LDR,rn,rt,rm);
emit_u16_with_pool(_jit, THUMB_LDR|(_u3(rm)<<6)|(_u3(rn)<<3)|_u3(rt));
}
static void
@ -2975,3 +2998,58 @@ emit_veneer(jit_state_t *_jit, jit_pointer_t target)
emit_u16(_jit, THUMB_MOV|((_u4(rd)&8)<<4)|(_u4(tmp)<<3)|(rd&7));
emit_u32(_jit, (uint32_t) target);
}
static void
ldr_atomic(jit_state_t *_jit, int32_t dst, int32_t loc)
{
T1_DMB(_jit, DMB_ISH);
ldr_i(_jit, dst, loc);
T1_DMB(_jit, DMB_ISH);
}
static void
str_atomic(jit_state_t *_jit, int32_t loc, int32_t val)
{
T1_DMB(_jit, DMB_ISH);
str_i(_jit, loc, val);
T1_DMB(_jit, DMB_ISH);
}
static void
swap_atomic(jit_state_t *_jit, int32_t dst, int32_t loc, int32_t val)
{
int32_t result = jit_gpr_regno(get_temp_gpr(_jit));
int32_t val_or_tmp = dst == val ? jit_gpr_regno(get_temp_gpr(_jit)) : val;
movr(_jit, val_or_tmp, val);
T1_DMB(_jit, DMB_ISH);
void *retry = jit_address(_jit);
T1_LDREX(_jit, dst, loc, 0);
T1_STREX(_jit, result, val_or_tmp, loc, 0);
jit_patch_there(_jit, bnei(_jit, result, 0), retry);
T1_DMB(_jit, DMB_ISH);
if (dst == val) unget_temp_gpr(_jit);
unget_temp_gpr(_jit);
}
static void
cas_atomic(jit_state_t *_jit, int32_t dst, int32_t loc, int32_t expected,
int32_t desired)
{
int32_t dst_or_tmp;
if (dst == loc || dst == expected || dst == expected)
dst_or_tmp = jit_gpr_regno(get_temp_gpr(_jit));
else
dst_or_tmp = dst;
T1_DMB(_jit, DMB_ISH);
void *retry = jit_address(_jit);
T1_LDREX(_jit, dst_or_tmp, loc, 0);
jit_reloc_t bad = bner(_jit, dst_or_tmp, expected);
int result = jit_gpr_regno(get_temp_gpr(_jit));
T1_STREX(_jit, result, desired, loc, 0);
jit_patch_there(_jit, bnei(_jit, result, 0), retry);
unget_temp_gpr(_jit);
jit_patch_here(_jit, bad);
T1_DMB(_jit, DMB_ISH);
movr(_jit, dst, dst_or_tmp);
unget_temp_gpr(_jit);
}

View file

@ -96,10 +96,6 @@ static struct jit_literal_pool* alloc_literal_pool(jit_state_t *_jit,
size_t capacity);
static void reset_literal_pool(jit_state_t *_jit,
struct jit_literal_pool *pool);
static void grow_literal_pool(jit_state_t *_jit);
static jit_bool_t add_literal_pool_entry(jit_state_t *_jit,
struct jit_literal_pool_entry entry,
uint32_t max_offset);
static jit_bool_t add_pending_literal(jit_state_t *_jit, jit_reloc_t src,
uint8_t max_offset_bits);
static void remove_pending_literal(jit_state_t *_jit, jit_reloc_t src);
@ -1279,9 +1275,11 @@ static jit_bool_t
add_literal_pool_entry(jit_state_t *_jit, struct jit_literal_pool_entry entry,
uint32_t max_offset)
{
if (_jit->overflow)
return 1;
if (max_offset <= literal_pool_byte_size(_jit->pool)) {
emit_literal_pool(_jit, GUARD_NEEDED);
ASSERT(_jit->pool->size == 0);
return 0;
}

View file

@ -609,6 +609,30 @@ xchgr(jit_state_t *_jit, int32_t r0, int32_t r1)
mrm(_jit, 0x03, r7(r1), r7(r0));
}
static void
xchgrm(jit_state_t *_jit, int32_t val_and_dst, int32_t loc)
{
rex(_jit, 0, WIDE, val_and_dst, _NOREG, loc);
ic(_jit, 0x87);
rx(_jit, val_and_dst, 0, loc, _NOREG, _SCL1);
}
static void
lock(jit_state_t *_jit)
{
ic(_jit, 0xf0);
}
static void
cmpxchgmr(jit_state_t *_jit, int32_t loc, int32_t desired)
{
lock(_jit);
rex(_jit, 0, WIDE, desired, _NOREG, loc);
ic(_jit, 0x0f);
ic(_jit, 0xb1);
rx(_jit, desired, 0, loc, _NOREG, _SCL1);
}
static void
testr(jit_state_t *_jit, int32_t r0, int32_t r1)
{
@ -2634,3 +2658,98 @@ retval_l(jit_state_t *_jit, int32_t r0)
movr(_jit, r0, _RAX_REGNO);
}
#endif
static void
mfence(jit_state_t *_jit)
{
ic(_jit, 0x0f);
ic(_jit, 0xae);
ic(_jit, 0xf0);
}
static void
ldr_atomic(jit_state_t *_jit, int32_t dst, int32_t loc)
{
#if __X64
ldr_l(_jit, dst, loc);
#else
ldr_i(_jit, dst, loc);
#endif
}
static void
str_atomic(jit_state_t *_jit, int32_t loc, int32_t val)
{
#if __X64
str_l(_jit, loc, val);
#else
str_i(_jit, loc, val);
#endif
mfence(_jit);
}
static void
swap_atomic(jit_state_t *_jit, int32_t dst, int32_t loc, int32_t val)
{
if (dst == val) {
xchgrm(_jit, dst, loc);
} else {
int32_t tmp = jit_gpr_regno(get_temp_gpr(_jit));
movr(_jit, tmp, val);
xchgrm(_jit, tmp, loc);
movr(_jit, dst, tmp);
unget_temp_gpr(_jit);
}
}
static void
cas_atomic(jit_state_t *_jit, int32_t dst, int32_t loc, int32_t expected,
int32_t desired)
{
ASSERT(loc != expected);
ASSERT(loc != desired);
if (dst == jit_gpr_regno(_RAX)) {
if (loc == dst) {
int32_t tmp = jit_gpr_regno(get_temp_gpr(_jit));
movr(_jit, tmp ,loc);
movr(_jit, dst, expected);
cmpxchgmr(_jit, tmp, desired);
unget_temp_gpr(_jit);
} else {
movr(_jit, dst, expected);
cmpxchgmr(_jit, loc, desired);
}
} else if (loc == jit_gpr_regno(_RAX)) {
int32_t tmp = jit_gpr_regno(get_temp_gpr(_jit));
movr(_jit, tmp, loc);
movr(_jit, jit_gpr_regno(_RAX), expected);
cmpxchgmr(_jit, tmp, desired);
movr(_jit, dst, jit_gpr_regno(_RAX));
movr(_jit, loc, tmp);
unget_temp_gpr(_jit);
} else if (expected == jit_gpr_regno(_RAX)) {
int32_t tmp = jit_gpr_regno(get_temp_gpr(_jit));
movr(_jit, tmp, expected);
cmpxchgmr(_jit, loc, desired);
movr(_jit, dst, jit_gpr_regno(_RAX));
movr(_jit, expected, tmp);
unget_temp_gpr(_jit);
} else if (desired == jit_gpr_regno(_RAX)) {
int32_t tmp = jit_gpr_regno(get_temp_gpr(_jit));
movr(_jit, tmp, desired);
movr(_jit, jit_gpr_regno(_RAX), expected);
cmpxchgmr(_jit, loc, tmp);
movr(_jit, dst, jit_gpr_regno(_RAX));
movr(_jit, desired, tmp);
unget_temp_gpr(_jit);
} else {
int32_t tmp = jit_gpr_regno(get_temp_gpr(_jit));
movr(_jit, tmp, jit_gpr_regno(_RAX));
movr(_jit, jit_gpr_regno(_RAX), expected);
cmpxchgmr(_jit, loc, desired);
movr(_jit, dst, jit_gpr_regno(_RAX));
movr(_jit, jit_gpr_regno(_RAX), tmp);
unget_temp_gpr(_jit);
}
}

View file

@ -1,6 +1,5 @@
TESTS=$(sort $(basename $(wildcard *.c)))
TARGETS=native ia32 aarch64
ALL_TARGETS=$(TARGETS) armv7
TARGETS=native ia32 aarch64 armv7
# Suitable values of cross-compiler variables for Debian:
#
@ -55,9 +54,9 @@ test-armv7-%: CC = $(CC_ARMv7)
test-armv7-%: %.c lightening-armv7.o test.h
$(CC) $(CFLAGS) $(CPPFLAGS) -I.. -o $@ lightening-armv7.o $<
.PRECIOUS: $(foreach TARGET,$(ALL_TARGETS),$(addprefix test-$(TARGET)-,$(TESTS)))
.PRECIOUS: $(foreach TARGET,$(ALL_TARGETS),lightening-$(TARGET).o)
.PRECIOUS: $(foreach TARGET,$(TARGETS),$(addprefix test-$(TARGET)-,$(TESTS)))
.PRECIOUS: $(foreach TARGET,$(TARGETS),lightening-$(TARGET).o)
clean:
rm -f $(foreach TARGET,$(ALL_TARGETS),$(addprefix test-$(TARGET)-,$(TESTS)))
rm -f $(foreach TARGET,$(ALL_TARGETS),lightening-$(TARGET).o)
rm -f $(foreach TARGET,$(TARGETS),$(addprefix test-$(TARGET)-,$(TESTS)))
rm -f $(foreach TARGET,$(TARGETS),lightening-$(TARGET).o)