]>
git.proxmox.com Git - mirror_qemu.git/blob - target/riscv/insn_trans/trans_rvi.inc.c
2 * RISC-V translation routines for the RVXI Base Integer Instruction Set.
4 * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
5 * Copyright (c) 2018 Peer Adelt, peer.adelt@hni.uni-paderborn.de
6 * Bastian Koppelmann, kbastian@mail.uni-paderborn.de
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2 or later, as published by the Free Software Foundation.
12 * This program is distributed in the hope it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
21 static bool trans_lui(DisasContext
*ctx
, arg_lui
*a
)
24 tcg_gen_movi_tl(cpu_gpr
[a
->rd
], a
->imm
);
29 static bool trans_auipc(DisasContext
*ctx
, arg_auipc
*a
)
32 tcg_gen_movi_tl(cpu_gpr
[a
->rd
], a
->imm
+ ctx
->base
.pc_next
);
37 static bool trans_jal(DisasContext
*ctx
, arg_jal
*a
)
39 gen_jal(ctx
, a
->rd
, a
->imm
);
43 static bool trans_jalr(DisasContext
*ctx
, arg_jalr
*a
)
45 gen_jalr(ctx
, OPC_RISC_JALR
, a
->rd
, a
->rs1
, a
->imm
);
49 static bool trans_beq(DisasContext
*ctx
, arg_beq
*a
)
51 gen_branch(ctx
, OPC_RISC_BEQ
, a
->rs1
, a
->rs2
, a
->imm
);
55 static bool trans_bne(DisasContext
*ctx
, arg_bne
*a
)
57 gen_branch(ctx
, OPC_RISC_BNE
, a
->rs1
, a
->rs2
, a
->imm
);
61 static bool trans_blt(DisasContext
*ctx
, arg_blt
*a
)
63 gen_branch(ctx
, OPC_RISC_BLT
, a
->rs1
, a
->rs2
, a
->imm
);
67 static bool trans_bge(DisasContext
*ctx
, arg_bge
*a
)
69 gen_branch(ctx
, OPC_RISC_BGE
, a
->rs1
, a
->rs2
, a
->imm
);
73 static bool trans_bltu(DisasContext
*ctx
, arg_bltu
*a
)
75 gen_branch(ctx
, OPC_RISC_BLTU
, a
->rs1
, a
->rs2
, a
->imm
);
79 static bool trans_bgeu(DisasContext
*ctx
, arg_bgeu
*a
)
82 gen_branch(ctx
, OPC_RISC_BGEU
, a
->rs1
, a
->rs2
, a
->imm
);
86 static bool trans_lb(DisasContext
*ctx
, arg_lb
*a
)
88 gen_load(ctx
, OPC_RISC_LB
, a
->rd
, a
->rs1
, a
->imm
);
92 static bool trans_lh(DisasContext
*ctx
, arg_lh
*a
)
94 gen_load(ctx
, OPC_RISC_LH
, a
->rd
, a
->rs1
, a
->imm
);
98 static bool trans_lw(DisasContext
*ctx
, arg_lw
*a
)
100 gen_load(ctx
, OPC_RISC_LW
, a
->rd
, a
->rs1
, a
->imm
);
104 static bool trans_lbu(DisasContext
*ctx
, arg_lbu
*a
)
106 gen_load(ctx
, OPC_RISC_LBU
, a
->rd
, a
->rs1
, a
->imm
);
110 static bool trans_lhu(DisasContext
*ctx
, arg_lhu
*a
)
112 gen_load(ctx
, OPC_RISC_LHU
, a
->rd
, a
->rs1
, a
->imm
);
116 static bool trans_sb(DisasContext
*ctx
, arg_sb
*a
)
118 gen_store(ctx
, OPC_RISC_SB
, a
->rs1
, a
->rs2
, a
->imm
);
122 static bool trans_sh(DisasContext
*ctx
, arg_sh
*a
)
124 gen_store(ctx
, OPC_RISC_SH
, a
->rs1
, a
->rs2
, a
->imm
);
128 static bool trans_sw(DisasContext
*ctx
, arg_sw
*a
)
130 gen_store(ctx
, OPC_RISC_SW
, a
->rs1
, a
->rs2
, a
->imm
);
134 #ifdef TARGET_RISCV64
135 static bool trans_lwu(DisasContext
*ctx
, arg_lwu
*a
)
137 gen_load(ctx
, OPC_RISC_LWU
, a
->rd
, a
->rs1
, a
->imm
);
141 static bool trans_ld(DisasContext
*ctx
, arg_ld
*a
)
143 gen_load(ctx
, OPC_RISC_LD
, a
->rd
, a
->rs1
, a
->imm
);
147 static bool trans_sd(DisasContext
*ctx
, arg_sd
*a
)
149 gen_store(ctx
, OPC_RISC_SD
, a
->rs1
, a
->rs2
, a
->imm
);
154 static bool trans_addi(DisasContext
*ctx
, arg_addi
*a
)
156 gen_arith_imm(ctx
, OPC_RISC_ADDI
, a
->rd
, a
->rs1
, a
->imm
);
160 static bool trans_slti(DisasContext
*ctx
, arg_slti
*a
)
162 gen_arith_imm(ctx
, OPC_RISC_SLTI
, a
->rd
, a
->rs1
, a
->imm
);
166 static bool trans_sltiu(DisasContext
*ctx
, arg_sltiu
*a
)
168 gen_arith_imm(ctx
, OPC_RISC_SLTIU
, a
->rd
, a
->rs1
, a
->imm
);
172 static bool trans_xori(DisasContext
*ctx
, arg_xori
*a
)
174 gen_arith_imm(ctx
, OPC_RISC_XORI
, a
->rd
, a
->rs1
, a
->imm
);
177 static bool trans_ori(DisasContext
*ctx
, arg_ori
*a
)
179 gen_arith_imm(ctx
, OPC_RISC_ORI
, a
->rd
, a
->rs1
, a
->imm
);
182 static bool trans_andi(DisasContext
*ctx
, arg_andi
*a
)
184 gen_arith_imm(ctx
, OPC_RISC_ANDI
, a
->rd
, a
->rs1
, a
->imm
);
187 static bool trans_slli(DisasContext
*ctx
, arg_slli
*a
)
189 gen_arith_imm(ctx
, OPC_RISC_SLLI
, a
->rd
, a
->rs1
, a
->shamt
);
193 static bool trans_srli(DisasContext
*ctx
, arg_srli
*a
)
195 gen_arith_imm(ctx
, OPC_RISC_SHIFT_RIGHT_I
, a
->rd
, a
->rs1
, a
->shamt
);
199 static bool trans_srai(DisasContext
*ctx
, arg_srai
*a
)
201 gen_arith_imm(ctx
, OPC_RISC_SHIFT_RIGHT_I
, a
->rd
, a
->rs1
, a
->shamt
| 0x400);
205 static bool trans_add(DisasContext
*ctx
, arg_add
*a
)
207 gen_arith(ctx
, OPC_RISC_ADD
, a
->rd
, a
->rs1
, a
->rs2
);
211 static bool trans_sub(DisasContext
*ctx
, arg_sub
*a
)
213 gen_arith(ctx
, OPC_RISC_SUB
, a
->rd
, a
->rs1
, a
->rs2
);
217 static bool trans_sll(DisasContext
*ctx
, arg_sll
*a
)
219 gen_arith(ctx
, OPC_RISC_SLL
, a
->rd
, a
->rs1
, a
->rs2
);
223 static bool trans_slt(DisasContext
*ctx
, arg_slt
*a
)
225 gen_arith(ctx
, OPC_RISC_SLT
, a
->rd
, a
->rs1
, a
->rs2
);
229 static bool trans_sltu(DisasContext
*ctx
, arg_sltu
*a
)
231 gen_arith(ctx
, OPC_RISC_SLTU
, a
->rd
, a
->rs1
, a
->rs2
);
235 static bool trans_xor(DisasContext
*ctx
, arg_xor
*a
)
237 gen_arith(ctx
, OPC_RISC_XOR
, a
->rd
, a
->rs1
, a
->rs2
);
241 static bool trans_srl(DisasContext
*ctx
, arg_srl
*a
)
243 gen_arith(ctx
, OPC_RISC_SRL
, a
->rd
, a
->rs1
, a
->rs2
);
247 static bool trans_sra(DisasContext
*ctx
, arg_sra
*a
)
249 gen_arith(ctx
, OPC_RISC_SRA
, a
->rd
, a
->rs1
, a
->rs2
);
253 static bool trans_or(DisasContext
*ctx
, arg_or
*a
)
255 gen_arith(ctx
, OPC_RISC_OR
, a
->rd
, a
->rs1
, a
->rs2
);
259 static bool trans_and(DisasContext
*ctx
, arg_and
*a
)
261 gen_arith(ctx
, OPC_RISC_AND
, a
->rd
, a
->rs1
, a
->rs2
);
265 #ifdef TARGET_RISCV64
266 static bool trans_addiw(DisasContext
*ctx
, arg_addiw
*a
)
268 gen_arith_imm(ctx
, OPC_RISC_ADDIW
, a
->rd
, a
->rs1
, a
->imm
);
272 static bool trans_slliw(DisasContext
*ctx
, arg_slliw
*a
)
274 gen_arith_imm(ctx
, OPC_RISC_SLLIW
, a
->rd
, a
->rs1
, a
->shamt
);
278 static bool trans_srliw(DisasContext
*ctx
, arg_srliw
*a
)
280 gen_arith_imm(ctx
, OPC_RISC_SHIFT_RIGHT_IW
, a
->rd
, a
->rs1
, a
->shamt
);
284 static bool trans_sraiw(DisasContext
*ctx
, arg_sraiw
*a
)
286 gen_arith_imm(ctx
, OPC_RISC_SHIFT_RIGHT_IW
, a
->rd
, a
->rs1
,
291 static bool trans_addw(DisasContext
*ctx
, arg_addw
*a
)
293 gen_arith(ctx
, OPC_RISC_ADDW
, a
->rd
, a
->rs1
, a
->rs2
);
297 static bool trans_subw(DisasContext
*ctx
, arg_subw
*a
)
299 gen_arith(ctx
, OPC_RISC_SUBW
, a
->rd
, a
->rs1
, a
->rs2
);
303 static bool trans_sllw(DisasContext
*ctx
, arg_sllw
*a
)
305 gen_arith(ctx
, OPC_RISC_SLLW
, a
->rd
, a
->rs1
, a
->rs2
);
309 static bool trans_srlw(DisasContext
*ctx
, arg_srlw
*a
)
311 gen_arith(ctx
, OPC_RISC_SRLW
, a
->rd
, a
->rs1
, a
->rs2
);
315 static bool trans_sraw(DisasContext
*ctx
, arg_sraw
*a
)
317 gen_arith(ctx
, OPC_RISC_SRAW
, a
->rd
, a
->rs1
, a
->rs2
);
322 static bool trans_fence(DisasContext
*ctx
, arg_fence
*a
)
324 /* FENCE is a full memory barrier. */
325 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
329 static bool trans_fence_i(DisasContext
*ctx
, arg_fence_i
*a
)
332 * FENCE_I is a no-op in QEMU,
333 * however we need to end the translation block
335 tcg_gen_movi_tl(cpu_pc
, ctx
->pc_succ_insn
);
336 tcg_gen_exit_tb(NULL
, 0);
337 ctx
->base
.is_jmp
= DISAS_NORETURN
;
341 #define RISCV_OP_CSR_PRE do {\
342 source1 = tcg_temp_new(); \
343 csr_store = tcg_temp_new(); \
344 dest = tcg_temp_new(); \
345 rs1_pass = tcg_temp_new(); \
346 gen_get_gpr(source1, a->rs1); \
347 tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); \
348 tcg_gen_movi_tl(rs1_pass, a->rs1); \
349 tcg_gen_movi_tl(csr_store, a->csr); \
353 #define RISCV_OP_CSR_POST do {\
355 gen_set_gpr(a->rd, dest); \
356 tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn); \
357 tcg_gen_exit_tb(NULL, 0); \
358 ctx->base.is_jmp = DISAS_NORETURN; \
359 tcg_temp_free(source1); \
360 tcg_temp_free(csr_store); \
361 tcg_temp_free(dest); \
362 tcg_temp_free(rs1_pass); \
366 static bool trans_csrrw(DisasContext
*ctx
, arg_csrrw
*a
)
368 TCGv source1
, csr_store
, dest
, rs1_pass
;
370 gen_helper_csrrw(dest
, cpu_env
, source1
, csr_store
);
375 static bool trans_csrrs(DisasContext
*ctx
, arg_csrrs
*a
)
377 TCGv source1
, csr_store
, dest
, rs1_pass
;
379 gen_helper_csrrs(dest
, cpu_env
, source1
, csr_store
, rs1_pass
);
384 static bool trans_csrrc(DisasContext
*ctx
, arg_csrrc
*a
)
386 TCGv source1
, csr_store
, dest
, rs1_pass
;
388 gen_helper_csrrc(dest
, cpu_env
, source1
, csr_store
, rs1_pass
);
393 static bool trans_csrrwi(DisasContext
*ctx
, arg_csrrwi
*a
)
395 TCGv source1
, csr_store
, dest
, rs1_pass
;
397 gen_helper_csrrw(dest
, cpu_env
, rs1_pass
, csr_store
);
402 static bool trans_csrrsi(DisasContext
*ctx
, arg_csrrsi
*a
)
404 TCGv source1
, csr_store
, dest
, rs1_pass
;
406 gen_helper_csrrs(dest
, cpu_env
, rs1_pass
, csr_store
, rs1_pass
);
411 static bool trans_csrrci(DisasContext
*ctx
, arg_csrrci
*a
)
413 TCGv source1
, csr_store
, dest
, rs1_pass
;
415 gen_helper_csrrc(dest
, cpu_env
, rs1_pass
, csr_store
, rs1_pass
);