aboutgitcodelistschat:MatrixIRC
path: root/cooker/emit.c
diff options
context:
space:
mode:
Diffstat (limited to 'cooker/emit.c')
-rw-r--r--cooker/emit.c52
1 files changed, 43 insertions, 9 deletions
diff --git a/cooker/emit.c b/cooker/emit.c
index 33355b6..7d13a02 100644
--- a/cooker/emit.c
+++ b/cooker/emit.c
@@ -217,18 +217,19 @@ void emit_store(struct gluten_ctx *g, struct gluten_offset dst,
* @iov: Pointer to msg_iov, already stored in gluten
* @iovlen: Pointer to msg_iovlen, already stored in gluten
* @dst: gluten destination to copy dereferenced data
+ * @alloc: Allocation size (alloc - len bytes filled with zeroes)
* @len: Maximum length of data to copy altogether
*/
struct gluten_offset emit_iovload(struct gluten_ctx *g,
struct gluten_offset iov,
struct gluten_offset iovlen,
- size_t len)
+ size_t alloc, size_t len)
{
struct op *op = (struct op *)gluten_ptr(&g->g, g->ip);
struct op_iovload *load = &op->op.iovload;
struct gluten_offset dst;
- dst = gluten_rw_alloc(g, len);
+ dst = gluten_rw_alloc(g, alloc);
op->type = OP_IOVLOAD;
@@ -237,6 +238,7 @@ struct gluten_offset emit_iovload(struct gluten_ctx *g,
load->dst = dst;
load->size = len;
+ load->zero_fill = alloc - len;
debug(" %i: OP_IOVLOAD: #%i < (#%i) as iovec (size: %lu)",
g->ip.offset, dst.offset, iov.offset, len);
@@ -294,6 +296,7 @@ void emit_resolvefd(struct gluten_ctx *g, enum type type,
* emit_bitwise(): Emit OP_BITWISE instruction: bitwise operation and store
* @g: gluten context
* @type: Type of operands
+ * @vec: Description of vector structure, NULL for scalar operation
* @op_type: Type of bitwise operation
* @dst: gluten pointer to destination operand, can be OFFSET_NULL
* @x: gluten pointer to first source operand
@@ -302,6 +305,7 @@ void emit_resolvefd(struct gluten_ctx *g, enum type type,
* Return: offset to destination operand, allocated here if not given
*/
struct gluten_offset emit_bitwise(struct gluten_ctx *g, enum type type,
+ struct vec_desc *vec,
enum bitwise_type op_type,
struct gluten_offset dst,
struct gluten_offset x,
@@ -311,6 +315,7 @@ struct gluten_offset emit_bitwise(struct gluten_ctx *g, enum type type,
struct op_bitwise *op_bitwise = &op->op.bitwise;
struct gluten_offset o;
struct bitwise_desc *desc;
+ char ip_str[BUFSIZ];
op->type = OP_BITWISE;
@@ -319,21 +324,42 @@ struct gluten_offset emit_bitwise(struct gluten_ctx *g, enum type type,
desc->size = gluten_size[type];
desc->type = op_type;
- if (dst.type == OFFSET_NULL)
- desc->dst = gluten_rw_alloc(g, desc->size);
- else
+
+ if (vec)
+ desc->vec = *vec;
+
+ if (dst.type == OFFSET_NULL) {
+ size_t dst_size;
+ if (vec) /* FIXME: UIO_MAXIOV (1024) is a dubious choice */
+ dst_size = (desc->size + sizeof(uint32_t)) * 1024;
+ else
+ dst_size = desc->size;
+
+ desc->dst = gluten_rw_alloc(g, dst_size);
+ } else {
desc->dst = dst;
+ }
+
desc->x = x;
desc->y = y;
op_bitwise->desc = o;
- debug(" %i: OP_BITWISE: %s: #%lu (size: %lu) := %s: #%lu %s %s: #%lu",
- g->ip.offset,
+ snprintf(ip_str, BUFSIZ, "%i", g->ip.offset);
+
+ debug(" %s: OP_BITWISE: %s: #%lu (size: %lu) := %s: #%lu %s %s: #%lu",
+ ip_str,
gluten_offset_name[desc->dst.type], desc->dst.offset, desc->size,
gluten_offset_name[desc->x.type], desc->x.offset,
bitwise_type_str[op_type],
gluten_offset_name[desc->y.type], desc->y.offset);
+ if (vec) {
+ memset(ip_str, ' ', strlen(ip_str));
+ debug(" %s vector start: %s: #%lu, length descriptor at %lu",
+ ip_str,
+ gluten_offset_name[vec->start.type], vec->start.offset,
+ vec->len_offset);
+ }
if (++g->ip.offset > INST_MAX)
die("Too many instructions");
@@ -345,12 +371,14 @@ struct gluten_offset emit_bitwise(struct gluten_ctx *g, enum type type,
* emit_cmp(): Emit OP_CMP instruction: compare data from two offsets
* @g: gluten context
* @cmp_type: Type of comparison
+ * @vec: Description of vector structure, NULL for scalar comparison
* @x: gluten pointer to first operand of comparison
* @y: gluten pointer to second operand of comparison
* @size: Size of comparison
* @jmp: Jump direction if comparison is true
*/
void emit_cmp(struct gluten_ctx *g, enum op_cmp_type cmp_type,
+ struct vec_desc *vec,
struct gluten_offset x, struct gluten_offset y, size_t size,
enum jump_type jmp)
{
@@ -367,6 +395,11 @@ void emit_cmp(struct gluten_ctx *g, enum op_cmp_type cmp_type,
desc->x = x;
desc->y = y;
desc->size = size;
+ if (vec)
+ desc->vec = *vec;
+ else
+ desc->vec.start.type = OFFSET_NULL;
+
desc->cmp = cmp_type;
desc->jmp.type = OFFSET_INSTRUCTION;
desc->jmp.offset = jmp;
@@ -388,17 +421,18 @@ void emit_cmp(struct gluten_ctx *g, enum op_cmp_type cmp_type,
* emit_cmp_field() - Emit OP_CMP for a given field type
* @g: gluten context
* @cmp: Type of comparison
+ * @vec: Description of vector structure, NULL for scalar comparison
* @field: Description of field from system call model
* @x: gluten pointer to first operand of comparison
* @y: gluten pointer to second operand of comparison
* @jmp: Jump direction if comparison is true
*/
void emit_cmp_field(struct gluten_ctx *g, enum op_cmp_type cmp,
- struct field *field,
+ struct vec_desc *vec, struct field *field,
struct gluten_offset x, struct gluten_offset y,
enum jump_type jmp)
{
- emit_cmp(g, cmp, x, y,
+ emit_cmp(g, cmp, vec, x, y,
field->size ? field->size : gluten_size[field->type],
jmp);
}