better handling of memory copies, fix vpx_get4x4sse_cs_svp64
[openpower-isa.git] / media / video / libvpx / variance_svp64_wrappers.c
1 #include <Python.h>
2 #include <stdint.h>
3 #include <stdio.h>
4
5 #include "pypowersim_wrapper_common.h"
6 #include "variance_svp64_wrappers.h"
7
8 uint32_t vpx_get_mb_ss_svp64(const int16_t *src_ptr) {
9 // It cannot be the same pointer as the original function, as it is really a separate CPU/RAM
10 // we have to memcpy from src_ptr to this pointer, the address was chosen arbitrarily
11 uint64_t src_ptr_svp64 = 0x100000;
12
13 // Create the pypowersim_state
14 pypowersim_state_t *state = pypowersim_prepare();
15
16 // Change the relevant elements, mandatory: body
17 //
18 state->binary = PyBytes_FromStringAndSize((const char *)&vpx_get_mb_ss_svp64_real, 1000);
19 // Set GPR #3 to the pointer
20 PyObject *address = PyLong_FromLongLong(src_ptr_svp64);
21 PyList_SetItem(state->initial_regs, 3, address);
22 // Load data into buffer from real memory
23 for (int i=0; i < 256; i += 4) {
24 PyObject *address = PyLong_FromLongLong(src_ptr_svp64);
25 uint64_t val = src_ptr[0];
26 val |= (uint64_t)(src_ptr[1]) << 16;
27 val |= (uint64_t)(src_ptr[2]) << 32;
28 val |= (uint64_t)(src_ptr[3]) << 48;
29 //printf("src: %p -> %04x %04x %04x %04x, val: %016x -> %p\n", src_ptr, src_ptr[0], src_ptr[1], src_ptr[2], src_ptr[3], val, src_ptr_svp64);
30 PyObject *word = PyLong_FromLongLong(val);
31 PyDict_SetItem(state->initial_mem, address, word);
32 src_ptr += 4;
33 src_ptr_svp64 += 8;
34 }
35
36 // Prepare the arguments object for the call
37 pypowersim_prepareargs(state);
38
39 // Call the function and get the resulting object
40 state->result_obj = PyObject_CallObject(state->simulator, state->args);
41 Py_DECREF(state->simulator);
42 Py_DECREF(state->args);
43 if (!state->result_obj) {
44 PyErr_Print();
45 printf("Error invoking 'run_a_simulation'\n");
46 }
47
48 // Get the GPRs from the result_obj
49 PyObject *final_regs = PyObject_GetAttrString(state->result_obj, "gpr");
50 if (!final_regs) {
51 PyErr_Print();
52 Py_DECREF(state->result_obj);
53 printf("Error getting final GPRs\n");
54 }
55
56 // GPR #3 holds the return value as an integer
57 PyObject *key = PyLong_FromLongLong(3);
58 PyObject *itm = PyDict_GetItem(final_regs, key);
59 PyObject *value = PyObject_GetAttrString(itm, "value");
60 uint64_t val = PyLong_AsLongLong(value);
61
62 // Return value
63 return (uint32_t) val;
64 }
65
66 uint32_t vpx_get4x4sse_cs_svp64(const uint8_t *src_ptr, int src_stride,
67 const uint8_t *ref_ptr, int ref_stride) {
68
69 // vpx_get4x4sse_cs_svp64_ref(src_ptr, src_stride, ref_ptr, ref_stride);
70
71 // It cannot be the same pointer as the original function, as it is really a separate CPU/RAM
72 // we have to memcpy from src_ptr to this pointer, the address was chosen arbitrarily
73 uint64_t src_ptr_svp64 = 0x100000;
74 uint64_t ref_ptr_svp64 = 0x200000;
75
76 // Create the pypowersim_state
77 pypowersim_state_t *state = pypowersim_prepare();
78
79 // Change the relevant elements, mandatory: body
80 state->binary = PyBytes_FromStringAndSize((const char *)&vpx_get4x4sse_cs_svp64_real, 1000);
81 // Set GPR #3 to the src_ptr
82 PyObject *src_address = PyLong_FromLongLong(src_ptr_svp64);
83 PyList_SetItem(state->initial_regs, 3, src_address);
84 // Load data into buffer from real memory
85 for (int r=0; r < 4; r++) {
86 PyObject *address = PyLong_FromLongLong(src_ptr_svp64);
87 uint64_t val = src_ptr[0];
88 val |= (uint64_t)(src_ptr[1]) << 16;
89 val |= (uint64_t)(src_ptr[2]) << 32;
90 val |= (uint64_t)(src_ptr[3]) << 48;
91 PyObject *word = PyLong_FromLongLong(val);
92 PyDict_SetItem(state->initial_mem, address, word);
93 src_ptr += src_stride;
94 src_ptr_svp64 += 8;
95 }
96
97 // Set GPR #4 to the src_stride
98 PyList_SetItem(state->initial_regs, 4, PyLong_FromLongLong(src_stride));
99
100 // Set GPR #5 to the ref_ptr
101 PyObject *ref_address = PyLong_FromLongLong(ref_ptr_svp64);
102 PyList_SetItem(state->initial_regs, 5, ref_address);
103 // Load data into buffer from real memory
104 for (int r=0; r < 4; r++) {
105 PyObject *address = PyLong_FromLongLong(ref_ptr_svp64);
106 uint64_t val = ref_ptr[0];
107 val |= (uint64_t)(ref_ptr[1]) << 16;
108 val |= (uint64_t)(ref_ptr[2]) << 32;
109 val |= (uint64_t)(ref_ptr[3]) << 48;
110 //printf("ref: %p -> %04x %04x %04x %04x, val: %016lx -> %p\n", ref_ptr, ref_ptr[0], ref_ptr[1], ref_ptr[2], ref_ptr[3], val, ref_ptr_svp64);
111 PyObject *word = PyLong_FromLongLong(val);
112 PyDict_SetItem(state->initial_mem, address, word);
113 ref_ptr += ref_stride;
114 ref_ptr_svp64 += 8;
115 }
116
117 // Set GPR #6 to the ref_stride
118 PyList_SetItem(state->initial_regs, 6, PyLong_FromLongLong(ref_stride));
119
120 // Prepare the arguments object for the call
121 pypowersim_prepareargs(state);
122
123 // Call the function and get the resulting object
124 state->result_obj = PyObject_CallObject(state->simulator, state->args);
125 Py_DECREF(state->simulator);
126 Py_DECREF(state->args);
127 if (!state->result_obj) {
128 PyErr_Print();
129 printf("Error invoking 'run_a_simulation'\n");
130 }
131
132 // Get the GPRs from the result_obj
133 PyObject *final_regs = PyObject_GetAttrString(state->result_obj, "gpr");
134 if (!final_regs) {
135 PyErr_Print();
136 Py_DECREF(state->result_obj);
137 printf("Error getting final GPRs\n");
138 }
139
140 // GPR #3 holds the return value as an integer
141 PyObject *key = PyLong_FromLongLong(3);
142 PyObject *itm = PyDict_GetItem(final_regs, key);
143 PyObject *value = PyObject_GetAttrString(itm, "value");
144 uint64_t val = PyLong_AsLongLong(value);
145
146 // Return value
147 return (uint32_t) val;
148
149 int distortion = 0;
150 int r, c;
151
152 for (r = 0; r < 4; ++r) {
153 for (c = 0; c < 4; ++c) {
154 int diff = src_ptr[c] - ref_ptr[c];
155 distortion += diff * diff;
156 }
157
158 src_ptr += src_stride;
159 ref_ptr += ref_stride;
160 }
161
162 return distortion;
163 }
164