harec

[hare] Hare compiler, written in C11 for POSIX OSs
Log | Files | Refs | README | LICENSE

genutil.c (2450B)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 #include "gen.h"
      5 #include "qbe.h"
      6 #include "types.h"
      7 #include "util.h"
      8 
      9 struct qbe_value
     10 mkqval(struct gen_context *ctx, struct gen_value *value)
     11 {
     12 	struct qbe_value qval = {0};
     13 	switch (value->kind) {
     14 	case GV_CONST:
     15 		qval.kind = QV_CONST;
     16 		qval.lval = value->lval; // XXX: Kind of hacky
     17 		break;
     18 	case GV_GLOBAL:
     19 		qval.kind = QV_GLOBAL;
     20 		qval.name = value->name;
     21 		qval.threadlocal = value->threadlocal;
     22 		break;
     23 	case GV_TEMP:
     24 		qval.kind = QV_TEMPORARY;
     25 		qval.name = value->name;
     26 		break;
     27 	}
     28 	qval.type = qtype_lookup(ctx, value->type, true);
     29 	return qval;
     30 }
     31 
     32 struct qbe_value
     33 mklval(struct gen_context *ctx, struct gen_value *value)
     34 {
     35 	struct qbe_value qval = mkqval(ctx, value);
     36 	qval.type = ctx->arch.ptr;
     37 	return qval;
     38 }
     39 
     40 struct qbe_value
     41 mkcopy(struct gen_context *ctx, struct gen_value *value, const char *fmt)
     42 {
     43 	struct qbe_value qval = mkqval(ctx, value);
     44 	struct qbe_value copy = mkqtmp(ctx, ctx->arch.ptr, fmt);
     45 	pushi(ctx->current, &copy, Q_COPY, &qval, NULL);
     46 	return copy;
     47 }
     48 
     49 struct qbe_value
     50 mkqtmp(struct gen_context *ctx, const struct qbe_type *qtype, const char *fmt)
     51 {
     52 	return (struct qbe_value){
     53 		.kind = QV_TEMPORARY,
     54 		.type = qtype,
     55 		.name = gen_name(&ctx->id, fmt),
     56 	};
     57 }
     58 
     59 struct gen_value
     60 mkgtemp(struct gen_context *ctx, const struct type *type, const char *fmt)
     61 {
     62 	return (struct gen_value){
     63 		.kind = GV_TEMP,
     64 		.type = type,
     65 		.name = gen_name(&ctx->id, fmt),
     66 	};
     67 }
     68 
     69 struct qbe_value
     70 mkrtfunc(struct gen_context *ctx, const char *name)
     71 {
     72 	return (struct qbe_value){
     73 		.kind = QV_GLOBAL,
     74 		.name = xstrdup(name),
     75 		.type = ctx->arch.ptr,
     76 	};
     77 }
     78 
     79 struct qbe_value
     80 mklabel(struct gen_context *ctx, struct qbe_statement *stmt, const char *fmt)
     81 {
     82 	struct qbe_value val;
     83 	val.kind = QV_LABEL;
     84 	val.name = xstrdup(genl(stmt, &ctx->id, fmt));
     85 	return val;
     86 }
     87 
     88 void
     89 branch_copyresult(struct gen_context *ctx,
     90 	struct gen_value result,
     91 	struct gen_value merged,
     92 	struct gen_value *out)
     93 {
     94 	// Branching expressions written in the _with style may need to
     95 	// consolodate each branch's result into a single temporary to return to
     96 	// the caller. This function facilitates that.
     97 	if (out
     98 		|| type_dealias(merged.type)->storage == STORAGE_VOID
     99 		|| type_dealias(result.type)->storage == STORAGE_VOID) {
    100 		return;
    101 	}
    102 	struct qbe_value qmerged = mkqval(ctx, &merged);
    103 	struct qbe_value qval = mkqval(ctx, &result);
    104 	pushi(ctx->current, &qmerged, Q_COPY, &qval, NULL);
    105 }