blob: 7a54997734f09dbd50bb4a5e9ed58b39d5139c3e [file] [log] [blame]
/* **********************************************************
* Copyright (c) 2022 Rivos, Inc. All rights reserved.
* **********************************************************/
/*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Rivos, Inc. nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL RIVOS, INC. OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
#include "../globals.h"
#include "encode_api.h"
#include "instr.h"
#include "decode.h"
#include "codec.h"
bool
is_isa_mode_legal(dr_isa_mode_t mode)
{
return (mode == DR_ISA_RV64 || mode == DR_ISA_REGDEPS);
}
app_pc
canonicalize_pc_target(dcontext_t *dcontext, app_pc pc)
{
return pc;
}
DR_API
app_pc
dr_app_pc_as_jump_target(dr_isa_mode_t isa_mode, app_pc pc)
{
return pc;
}
DR_API
app_pc
dr_app_pc_as_load_target(dr_isa_mode_t isa_mode, app_pc pc)
{
return pc;
}
byte *
decode_eflags_usage(void *drcontext, byte *pc, uint *usage, dr_opnd_query_flags_t flags)
{
*usage = 0; /* No eflags on RISC-V. */
return decode_next_pc(drcontext, pc);
}
byte *
decode_opcode(dcontext_t *dcontext, byte *pc, instr_t *instr)
{
/* FIXME i#3544: Not implemented */
ASSERT_NOT_IMPLEMENTED(false);
return NULL;
}
byte *
decode(void *drcontext, byte *pc, instr_t *instr)
{
return decode_common(drcontext, pc, pc, instr);
}
byte *
decode_from_copy(void *drcontext, byte *copy_pc, byte *orig_pc, instr_t *instr)
{
return decode_common(drcontext, copy_pc, orig_pc, instr);
}
byte *
decode_cti(void *drcontext, byte *pc, instr_t *instr)
{
dcontext_t *dcontext = (dcontext_t *)drcontext;
return decode(dcontext, pc, instr);
}
byte *
decode_next_pc(void *dcontext, byte *pc)
{
int width = instruction_width(*(int16_t *)pc);
return pc + width;
}
int
decode_sizeof(void *drcontext, byte *pc, int *num_prefixes)
{
return instruction_width(*(int16_t *)pc);
}
byte *
decode_raw(dcontext_t *dcontext, byte *pc, instr_t *instr)
{
/* FIXME i#3544: Not implemented */
ASSERT_NOT_IMPLEMENTED(false);
return NULL;
}
bool
decode_raw_is_jmp(dcontext_t *dcontext, byte *pc)
{
return ((*(uint *)pc & 0x7f) == 0x6f); /* JAL */
}
byte *
decode_raw_jmp_target(dcontext_t *dcontext, byte *pc)
{
/* Format of the J-type instruction:
* | 31 |30 21| 20 |19 12|11 7|6 0|
* | imm[20] | imm[10:1] | imm[11] | imm[19:12] | rd | opcode |
* ^------------------------------------------^
*/
uint enc = *(uint *)pc;
int32_t imm = (((enc >> 31) & 1) << 20) | (((enc >> 12) & 0xff) << 12) |
(((enc >> 20) & 1) << 11) | (((enc >> 21) & 0x3ff) << 1);
return pc + ((imm << 11) >> 11);
}
const instr_info_t *
instr_info_extra_opnds(const instr_info_t *info)
{
/* FIXME i#3544: Not implemented */
ASSERT_NOT_IMPLEMENTED(false);
return NULL;
}
byte
instr_info_opnd_type(const instr_info_t *info, bool src, int num)
{
/* FIXME i#3544: Not implemented */
ASSERT_NOT_IMPLEMENTED(false);
return 0;
}
const instr_info_t *
get_next_instr_info(const instr_info_t *info)
{
/* FIXME i#3544: Not implemented */
ASSERT_NOT_IMPLEMENTED(false);
return NULL;
}
byte
decode_first_opcode_byte(int opcode)
{
/* FIXME i#3544: Not implemented */
ASSERT_NOT_IMPLEMENTED(false);
return 0;
}
const instr_info_t *
opcode_to_encoding_info(uint opc, dr_isa_mode_t isa_mode)
{
return get_instruction_info(opc);
}
DR_API
const char *
decode_opcode_name(int opcode)
{
return get_opcode_name(opcode);
}
opnd_size_t
resolve_variable_size(decode_info_t *di, opnd_size_t sz, bool is_reg)
{
/* FIXME i#3544: Not implemented */
ASSERT_NOT_IMPLEMENTED(false);
return 0;
}
bool
optype_is_indir_reg(int optype)
{
/* FIXME i#3544: Not implemented */
ASSERT_NOT_IMPLEMENTED(false);
return false;
}
bool
optype_is_reg(int optype)
{
/* FIXME i#3544: Not implemented */
ASSERT_NOT_IMPLEMENTED(false);
return false;
}
bool
optype_is_gpr(int optype)
{
/* FIXME i#3544: Not implemented */
ASSERT_NOT_IMPLEMENTED(false);
return false;
}
#ifdef DEBUG
# ifndef STANDALONE_DECODER
void
check_encode_decode_consistency(dcontext_t *dcontext, instrlist_t *ilist)
{
/* FIXME i#3544: Not implemented */
ASSERT_NOT_IMPLEMENTED(false);
}
# endif /* STANDALONE_DECODER */
void
decode_debug_checks_arch(void)
{
/* FIXME i#3544: NYI */
}
#endif /* DEBUG */
#ifdef DECODE_UNIT_TEST
# include "instr_create_shared.h"
int
main()
{
bool res = true;
standalone_init();
standalone_exit();
return res;
}
#endif /* DECODE_UNIT_TEST */