Revision d5612f10 target-arm/translate-a64.c
b/target-arm/translate-a64.c | ||
---|---|---|
901 | 901 |
} |
902 | 902 |
} |
903 | 903 |
|
904 |
/* |
|
905 |
* C3.3.13 Load/store (unsigned immediate) |
|
906 |
* |
|
907 |
* 31 30 29 27 26 25 24 23 22 21 10 9 5 |
|
908 |
* +----+-------+---+-----+-----+------------+-------+------+ |
|
909 |
* |size| 1 1 1 | V | 0 1 | opc | imm12 | Rn | Rt | |
|
910 |
* +----+-------+---+-----+-----+------------+-------+------+ |
|
911 |
* |
|
912 |
* For non-vector: |
|
913 |
* size: 00-> byte, 01 -> 16 bit, 10 -> 32bit, 11 -> 64bit |
|
914 |
* opc: 00 -> store, 01 -> loadu, 10 -> loads 64, 11 -> loads 32 |
|
915 |
* For vector: |
|
916 |
* size is opc<1>:size<1:0> so 100 -> 128 bit; 110 and 111 unallocated |
|
917 |
* opc<0>: 0 -> store, 1 -> load |
|
918 |
* Rn: base address register (inc SP) |
|
919 |
* Rt: target register |
|
920 |
*/ |
|
921 |
static void disas_ldst_reg_unsigned_imm(DisasContext *s, uint32_t insn) |
|
922 |
{ |
|
923 |
int rt = extract32(insn, 0, 5); |
|
924 |
int rn = extract32(insn, 5, 5); |
|
925 |
unsigned int imm12 = extract32(insn, 10, 12); |
|
926 |
bool is_vector = extract32(insn, 26, 1); |
|
927 |
int size = extract32(insn, 30, 2); |
|
928 |
int opc = extract32(insn, 22, 2); |
|
929 |
unsigned int offset; |
|
930 |
|
|
931 |
TCGv_i64 tcg_addr; |
|
932 |
|
|
933 |
bool is_store; |
|
934 |
bool is_signed = false; |
|
935 |
bool is_extended = false; |
|
936 |
|
|
937 |
if (is_vector) { |
|
938 |
size |= (opc & 2) << 1; |
|
939 |
if (size > 4) { |
|
940 |
unallocated_encoding(s); |
|
941 |
return; |
|
942 |
} |
|
943 |
is_store = !extract32(opc, 0, 1); |
|
944 |
} else { |
|
945 |
if (size == 3 && opc == 2) { |
|
946 |
/* PRFM - prefetch */ |
|
947 |
return; |
|
948 |
} |
|
949 |
if (opc == 3 && size > 1) { |
|
950 |
unallocated_encoding(s); |
|
951 |
return; |
|
952 |
} |
|
953 |
is_store = (opc == 0); |
|
954 |
is_signed = extract32(opc, 1, 1); |
|
955 |
is_extended = (size < 3) && extract32(opc, 0, 1); |
|
956 |
} |
|
957 |
|
|
958 |
if (rn == 31) { |
|
959 |
gen_check_sp_alignment(s); |
|
960 |
} |
|
961 |
tcg_addr = read_cpu_reg_sp(s, rn, 1); |
|
962 |
offset = imm12 << size; |
|
963 |
tcg_gen_addi_i64(tcg_addr, tcg_addr, offset); |
|
964 |
|
|
965 |
if (is_vector) { |
|
966 |
if (is_store) { |
|
967 |
do_fp_st(s, rt, tcg_addr, size); |
|
968 |
} else { |
|
969 |
do_fp_ld(s, rt, tcg_addr, size); |
|
970 |
} |
|
971 |
} else { |
|
972 |
TCGv_i64 tcg_rt = cpu_reg(s, rt); |
|
973 |
if (is_store) { |
|
974 |
do_gpr_st(s, tcg_rt, tcg_addr, size); |
|
975 |
} else { |
|
976 |
do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, is_extended); |
|
977 |
} |
|
978 |
} |
|
979 |
} |
|
980 |
|
|
904 | 981 |
/* Load/store register (all forms) */ |
905 | 982 |
static void disas_ldst_reg(DisasContext *s, uint32_t insn) |
906 | 983 |
{ |
907 |
unsupported_encoding(s, insn); |
|
984 |
switch (extract32(insn, 24, 2)) { |
|
985 |
case 0: |
|
986 |
unsupported_encoding(s, insn); |
|
987 |
break; |
|
988 |
case 1: |
|
989 |
disas_ldst_reg_unsigned_imm(s, insn); |
|
990 |
break; |
|
991 |
default: |
|
992 |
unallocated_encoding(s); |
|
993 |
break; |
|
994 |
} |
|
908 | 995 |
} |
909 | 996 |
|
910 | 997 |
/* AdvSIMD load/store multiple structures */ |
Also available in: Unified diff