Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
L
libtcg
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Anton
libtcg
Commits
0b1347d2
Commit
0b1347d2
authored
8 years ago
by
Richard Henderson
Browse files
Options
Downloads
Patches
Plain Diff
target-hppa: Implement shifts and deposits
Signed-off-by:
Richard Henderson
<
rth@twiddle.net
>
parent
7ad439df
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
target/hppa/translate.c
+309
-0
309 additions, 0 deletions
target/hppa/translate.c
with
309 additions
and
0 deletions
target/hppa/translate.c
+
309
−
0
View file @
0b1347d2
...
...
@@ -1719,6 +1719,311 @@ static ExitStatus trans_movb(DisasContext *ctx, uint32_t insn, bool is_imm)
return
do_cbranch
(
ctx
,
disp
,
n
,
&
cond
);
}
static
ExitStatus
trans_shrpw_sar
(
DisasContext
*
ctx
,
uint32_t
insn
,
const
DisasInsn
*
di
)
{
unsigned
rt
=
extract32
(
insn
,
0
,
5
);
unsigned
c
=
extract32
(
insn
,
13
,
3
);
unsigned
r1
=
extract32
(
insn
,
16
,
5
);
unsigned
r2
=
extract32
(
insn
,
21
,
5
);
TCGv
dest
;
if
(
c
)
{
nullify_over
(
ctx
);
}
dest
=
dest_gpr
(
ctx
,
rt
);
if
(
r1
==
0
)
{
tcg_gen_ext32u_tl
(
dest
,
load_gpr
(
ctx
,
r2
));
tcg_gen_shr_tl
(
dest
,
dest
,
cpu_sar
);
}
else
if
(
r1
==
r2
)
{
TCGv_i32
t32
=
tcg_temp_new_i32
();
tcg_gen_trunc_tl_i32
(
t32
,
load_gpr
(
ctx
,
r2
));
tcg_gen_rotr_i32
(
t32
,
t32
,
cpu_sar
);
tcg_gen_extu_i32_tl
(
dest
,
t32
);
tcg_temp_free_i32
(
t32
);
}
else
{
TCGv_i64
t
=
tcg_temp_new_i64
();
TCGv_i64
s
=
tcg_temp_new_i64
();
tcg_gen_concat_tl_i64
(
t
,
load_gpr
(
ctx
,
r2
),
load_gpr
(
ctx
,
r1
));
tcg_gen_extu_tl_i64
(
s
,
cpu_sar
);
tcg_gen_shr_i64
(
t
,
t
,
s
);
tcg_gen_trunc_i64_tl
(
dest
,
t
);
tcg_temp_free_i64
(
t
);
tcg_temp_free_i64
(
s
);
}
save_gpr
(
ctx
,
rt
,
dest
);
/* Install the new nullification. */
cond_free
(
&
ctx
->
null_cond
);
if
(
c
)
{
ctx
->
null_cond
=
do_sed_cond
(
c
,
dest
);
}
return
nullify_end
(
ctx
,
NO_EXIT
);
}
static
ExitStatus
trans_shrpw_imm
(
DisasContext
*
ctx
,
uint32_t
insn
,
const
DisasInsn
*
di
)
{
unsigned
rt
=
extract32
(
insn
,
0
,
5
);
unsigned
cpos
=
extract32
(
insn
,
5
,
5
);
unsigned
c
=
extract32
(
insn
,
13
,
3
);
unsigned
r1
=
extract32
(
insn
,
16
,
5
);
unsigned
r2
=
extract32
(
insn
,
21
,
5
);
unsigned
sa
=
31
-
cpos
;
TCGv
dest
,
t2
;
if
(
c
)
{
nullify_over
(
ctx
);
}
dest
=
dest_gpr
(
ctx
,
rt
);
t2
=
load_gpr
(
ctx
,
r2
);
if
(
r1
==
r2
)
{
TCGv_i32
t32
=
tcg_temp_new_i32
();
tcg_gen_trunc_tl_i32
(
t32
,
t2
);
tcg_gen_rotri_i32
(
t32
,
t32
,
sa
);
tcg_gen_extu_i32_tl
(
dest
,
t32
);
tcg_temp_free_i32
(
t32
);
}
else
if
(
r1
==
0
)
{
tcg_gen_extract_tl
(
dest
,
t2
,
sa
,
32
-
sa
);
}
else
{
TCGv
t0
=
tcg_temp_new
();
tcg_gen_extract_tl
(
t0
,
t2
,
sa
,
32
-
sa
);
tcg_gen_deposit_tl
(
dest
,
t0
,
cpu_gr
[
r1
],
32
-
sa
,
sa
);
tcg_temp_free
(
t0
);
}
save_gpr
(
ctx
,
rt
,
dest
);
/* Install the new nullification. */
cond_free
(
&
ctx
->
null_cond
);
if
(
c
)
{
ctx
->
null_cond
=
do_sed_cond
(
c
,
dest
);
}
return
nullify_end
(
ctx
,
NO_EXIT
);
}
static
ExitStatus
trans_extrw_sar
(
DisasContext
*
ctx
,
uint32_t
insn
,
const
DisasInsn
*
di
)
{
unsigned
clen
=
extract32
(
insn
,
0
,
5
);
unsigned
is_se
=
extract32
(
insn
,
10
,
1
);
unsigned
c
=
extract32
(
insn
,
13
,
3
);
unsigned
rt
=
extract32
(
insn
,
16
,
5
);
unsigned
rr
=
extract32
(
insn
,
21
,
5
);
unsigned
len
=
32
-
clen
;
TCGv
dest
,
src
,
tmp
;
if
(
c
)
{
nullify_over
(
ctx
);
}
dest
=
dest_gpr
(
ctx
,
rt
);
src
=
load_gpr
(
ctx
,
rr
);
tmp
=
tcg_temp_new
();
/* Recall that SAR is using big-endian bit numbering. */
tcg_gen_xori_tl
(
tmp
,
cpu_sar
,
TARGET_LONG_BITS
-
1
);
if
(
is_se
)
{
tcg_gen_sar_tl
(
dest
,
src
,
tmp
);
tcg_gen_sextract_tl
(
dest
,
dest
,
0
,
len
);
}
else
{
tcg_gen_shr_tl
(
dest
,
src
,
tmp
);
tcg_gen_extract_tl
(
dest
,
dest
,
0
,
len
);
}
tcg_temp_free
(
tmp
);
save_gpr
(
ctx
,
rt
,
dest
);
/* Install the new nullification. */
cond_free
(
&
ctx
->
null_cond
);
if
(
c
)
{
ctx
->
null_cond
=
do_sed_cond
(
c
,
dest
);
}
return
nullify_end
(
ctx
,
NO_EXIT
);
}
static
ExitStatus
trans_extrw_imm
(
DisasContext
*
ctx
,
uint32_t
insn
,
const
DisasInsn
*
di
)
{
unsigned
clen
=
extract32
(
insn
,
0
,
5
);
unsigned
pos
=
extract32
(
insn
,
5
,
5
);
unsigned
is_se
=
extract32
(
insn
,
10
,
1
);
unsigned
c
=
extract32
(
insn
,
13
,
3
);
unsigned
rt
=
extract32
(
insn
,
16
,
5
);
unsigned
rr
=
extract32
(
insn
,
21
,
5
);
unsigned
len
=
32
-
clen
;
unsigned
cpos
=
31
-
pos
;
TCGv
dest
,
src
;
if
(
c
)
{
nullify_over
(
ctx
);
}
dest
=
dest_gpr
(
ctx
,
rt
);
src
=
load_gpr
(
ctx
,
rr
);
if
(
is_se
)
{
tcg_gen_sextract_tl
(
dest
,
src
,
cpos
,
len
);
}
else
{
tcg_gen_extract_tl
(
dest
,
src
,
cpos
,
len
);
}
save_gpr
(
ctx
,
rt
,
dest
);
/* Install the new nullification. */
cond_free
(
&
ctx
->
null_cond
);
if
(
c
)
{
ctx
->
null_cond
=
do_sed_cond
(
c
,
dest
);
}
return
nullify_end
(
ctx
,
NO_EXIT
);
}
static
const
DisasInsn
table_sh_ex
[]
=
{
{
0xd0000000u
,
0xfc001fe0u
,
trans_shrpw_sar
},
{
0xd0000800u
,
0xfc001c00u
,
trans_shrpw_imm
},
{
0xd0001000u
,
0xfc001be0u
,
trans_extrw_sar
},
{
0xd0001800u
,
0xfc001800u
,
trans_extrw_imm
},
};
static
ExitStatus
trans_depw_imm_c
(
DisasContext
*
ctx
,
uint32_t
insn
,
const
DisasInsn
*
di
)
{
unsigned
clen
=
extract32
(
insn
,
0
,
5
);
unsigned
cpos
=
extract32
(
insn
,
5
,
5
);
unsigned
nz
=
extract32
(
insn
,
10
,
1
);
unsigned
c
=
extract32
(
insn
,
13
,
3
);
target_long
val
=
low_sextract
(
insn
,
16
,
5
);
unsigned
rt
=
extract32
(
insn
,
21
,
5
);
unsigned
len
=
32
-
clen
;
target_long
mask0
,
mask1
;
TCGv
dest
;
if
(
c
)
{
nullify_over
(
ctx
);
}
if
(
cpos
+
len
>
32
)
{
len
=
32
-
cpos
;
}
dest
=
dest_gpr
(
ctx
,
rt
);
mask0
=
deposit64
(
0
,
cpos
,
len
,
val
);
mask1
=
deposit64
(
-
1
,
cpos
,
len
,
val
);
if
(
nz
)
{
TCGv
src
=
load_gpr
(
ctx
,
rt
);
if
(
mask1
!=
-
1
)
{
tcg_gen_andi_tl
(
dest
,
src
,
mask1
);
src
=
dest
;
}
tcg_gen_ori_tl
(
dest
,
src
,
mask0
);
}
else
{
tcg_gen_movi_tl
(
dest
,
mask0
);
}
save_gpr
(
ctx
,
rt
,
dest
);
/* Install the new nullification. */
cond_free
(
&
ctx
->
null_cond
);
if
(
c
)
{
ctx
->
null_cond
=
do_sed_cond
(
c
,
dest
);
}
return
nullify_end
(
ctx
,
NO_EXIT
);
}
static
ExitStatus
trans_depw_imm
(
DisasContext
*
ctx
,
uint32_t
insn
,
const
DisasInsn
*
di
)
{
unsigned
clen
=
extract32
(
insn
,
0
,
5
);
unsigned
cpos
=
extract32
(
insn
,
5
,
5
);
unsigned
nz
=
extract32
(
insn
,
10
,
1
);
unsigned
c
=
extract32
(
insn
,
13
,
3
);
unsigned
rr
=
extract32
(
insn
,
16
,
5
);
unsigned
rt
=
extract32
(
insn
,
21
,
5
);
unsigned
rs
=
nz
?
rt
:
0
;
unsigned
len
=
32
-
clen
;
TCGv
dest
,
val
;
if
(
c
)
{
nullify_over
(
ctx
);
}
if
(
cpos
+
len
>
32
)
{
len
=
32
-
cpos
;
}
dest
=
dest_gpr
(
ctx
,
rt
);
val
=
load_gpr
(
ctx
,
rr
);
if
(
rs
==
0
)
{
tcg_gen_deposit_z_tl
(
dest
,
val
,
cpos
,
len
);
}
else
{
tcg_gen_deposit_tl
(
dest
,
cpu_gr
[
rs
],
val
,
cpos
,
len
);
}
save_gpr
(
ctx
,
rt
,
dest
);
/* Install the new nullification. */
cond_free
(
&
ctx
->
null_cond
);
if
(
c
)
{
ctx
->
null_cond
=
do_sed_cond
(
c
,
dest
);
}
return
nullify_end
(
ctx
,
NO_EXIT
);
}
static
ExitStatus
trans_depw_sar
(
DisasContext
*
ctx
,
uint32_t
insn
,
const
DisasInsn
*
di
)
{
unsigned
clen
=
extract32
(
insn
,
0
,
5
);
unsigned
nz
=
extract32
(
insn
,
10
,
1
);
unsigned
i
=
extract32
(
insn
,
12
,
1
);
unsigned
c
=
extract32
(
insn
,
13
,
3
);
unsigned
rt
=
extract32
(
insn
,
21
,
5
);
unsigned
rs
=
nz
?
rt
:
0
;
unsigned
len
=
32
-
clen
;
TCGv
val
,
mask
,
tmp
,
shift
,
dest
;
unsigned
msb
=
1U
<<
(
len
-
1
);
if
(
c
)
{
nullify_over
(
ctx
);
}
if
(
i
)
{
val
=
load_const
(
ctx
,
low_sextract
(
insn
,
16
,
5
));
}
else
{
val
=
load_gpr
(
ctx
,
extract32
(
insn
,
16
,
5
));
}
dest
=
dest_gpr
(
ctx
,
rt
);
shift
=
tcg_temp_new
();
tmp
=
tcg_temp_new
();
/* Convert big-endian bit numbering in SAR to left-shift. */
tcg_gen_xori_tl
(
shift
,
cpu_sar
,
TARGET_LONG_BITS
-
1
);
mask
=
tcg_const_tl
(
msb
+
(
msb
-
1
));
tcg_gen_and_tl
(
tmp
,
val
,
mask
);
if
(
rs
)
{
tcg_gen_shl_tl
(
mask
,
mask
,
shift
);
tcg_gen_shl_tl
(
tmp
,
tmp
,
shift
);
tcg_gen_andc_tl
(
dest
,
cpu_gr
[
rs
],
mask
);
tcg_gen_or_tl
(
dest
,
dest
,
tmp
);
}
else
{
tcg_gen_shl_tl
(
dest
,
tmp
,
shift
);
}
tcg_temp_free
(
shift
);
tcg_temp_free
(
mask
);
tcg_temp_free
(
tmp
);
save_gpr
(
ctx
,
rt
,
dest
);
/* Install the new nullification. */
cond_free
(
&
ctx
->
null_cond
);
if
(
c
)
{
ctx
->
null_cond
=
do_sed_cond
(
c
,
dest
);
}
return
nullify_end
(
ctx
,
NO_EXIT
);
}
static
const
DisasInsn
table_depw
[]
=
{
{
0xd4000000u
,
0xfc000be0u
,
trans_depw_sar
},
{
0xd4000800u
,
0xfc001800u
,
trans_depw_imm
},
{
0xd4001800u
,
0xfc001800u
,
trans_depw_imm_c
},
};
static
ExitStatus
trans_be
(
DisasContext
*
ctx
,
uint32_t
insn
,
bool
is_l
)
{
unsigned
n
=
extract32
(
insn
,
1
,
1
);
...
...
@@ -1874,6 +2179,10 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
return
trans_movb
(
ctx
,
insn
,
false
);
case
0x33
:
return
trans_movb
(
ctx
,
insn
,
true
);
case
0x34
:
return
translate_table
(
ctx
,
insn
,
table_sh_ex
);
case
0x35
:
return
translate_table
(
ctx
,
insn
,
table_depw
);
case
0x38
:
return
trans_be
(
ctx
,
insn
,
false
);
case
0x39
:
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment