diff options
Diffstat (limited to 'target/s390x/tcg/mem_helper.c')
| -rw-r--r-- | target/s390x/tcg/mem_helper.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/target/s390x/tcg/mem_helper.c b/target/s390x/tcg/mem_helper.c index b5523ef3c7..fc52aa128b 100644 --- a/target/s390x/tcg/mem_helper.c +++ b/target/s390x/tcg/mem_helper.c @@ -547,6 +547,26 @@ void HELPER(mvc)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src) do_helper_mvc(env, l, dest, src, GETPC()); } +/* move right to left */ +void HELPER(mvcrl)(CPUS390XState *env, uint64_t l, uint64_t dest, uint64_t src) +{ + const int mmu_idx = cpu_mmu_index(env, false); + const uint64_t ra = GETPC(); + S390Access srca, desta; + int32_t i; + + /* MVCRL always copies one more byte than specified - maximum is 256 */ + l++; + + srca = access_prepare(env, src, l, MMU_DATA_LOAD, mmu_idx, ra); + desta = access_prepare(env, dest, l, MMU_DATA_STORE, mmu_idx, ra); + + for (i = l - 1; i >= 0; i--) { + uint8_t byte = access_get_byte(env, &srca, i, ra); + access_set_byte(env, &desta, i, byte, ra); + } +} + /* move inverse */ void HELPER(mvcin)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src) { |