From 8bfbe4d6199b6b14ddbcf213ec681cdcb8374c59 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <wolfgang.linux@bumiller.com>
Date: Sat, 5 May 2012 00:03:18 +0200
Subject: [PATCH] Preparing to generate code from the IR - code_write should
 return a bool, and take a filename rather than use program.dat hardcoded

---
 asm.c   |  2 +-
 code.c  | 28 ++++++++++++++++++----------
 gmqcc.h |  2 +-
 ir.c    | 24 ++++++++++++++++++++++++
 4 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/asm.c b/asm.c
index 1c00199..1619438 100644
--- a/asm.c
+++ b/asm.c
@@ -65,7 +65,7 @@ void asm_init(const char *file, FILE **fp) {
 }
 void asm_close(FILE *fp) {
     fclose(fp);
-    code_write();
+    code_write("program.dat");
 }
 void asm_clear() {
     size_t i = 0;
diff --git a/code.c b/code.c
index 64b6260..81e8aa6 100644
--- a/code.c
+++ b/code.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2012
- *     Dale Weiler
+ *     Dale Weiler, Wolfgang Bumiller
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy of
  * this software and associated documentation files (the "Software"), to deal in
@@ -144,7 +144,7 @@ void code_test() {
     code_statements_add(s3);
 }
 
-void code_write() {
+bool code_write(const char *filename) {
     prog_header  code_header;
     FILE        *fp           = NULL;
     size_t       it           = 2;
@@ -184,14 +184,21 @@ void code_write() {
     util_endianswap(code_functions_data,  code_functions_elements,  sizeof(prog_section_function));
     util_endianswap(code_globals_data,    code_globals_elements,    sizeof(int32_t));
 
-    fp = fopen("program.dat", "wb");
-    fwrite(&code_header,         1, sizeof(prog_header), fp);
-    fwrite(code_statements_data, 1, sizeof(prog_section_statement)*code_statements_elements, fp);
-    fwrite(code_defs_data,       1, sizeof(prog_section_def)      *code_defs_elements,       fp);
-    fwrite(code_fields_data,     1, sizeof(prog_section_field)    *code_fields_elements,     fp);
-    fwrite(code_functions_data,  1, sizeof(prog_section_function) *code_functions_elements,  fp);
-    fwrite(code_globals_data,    1, sizeof(int32_t)               *code_globals_elements,    fp);
-    fwrite(code_chars_data,      1, 1                             *code_chars_elements,      fp);
+    fp = fopen(filename, "wb");
+    if (!fp)
+        return false;
+
+    if (1 != fwrite(&code_header,         sizeof(prog_header), 1, fp) ||
+        1 != fwrite(code_statements_data, sizeof(prog_section_statement)*code_statements_elements, 1, fp) ||
+        1 != fwrite(code_defs_data,       sizeof(prog_section_def)      *code_defs_elements,       1, fp) ||
+        1 != fwrite(code_fields_data,     sizeof(prog_section_field)    *code_fields_elements,     1, fp) ||
+        1 != fwrite(code_functions_data,  sizeof(prog_section_function) *code_functions_elements,  1, fp) ||
+        1 != fwrite(code_globals_data,    sizeof(int32_t)               *code_globals_elements,    1, fp) ||
+        1 != fwrite(code_chars_data,      1                             *code_chars_elements,      1, fp))
+    {
+        fclose(fp);
+        return false;
+    }
 
     util_debug("GEN","HEADER:\n");
     util_debug("GEN","    version:    = %d\n", code_header.version );
@@ -254,4 +261,5 @@ void code_write() {
     mem_d(code_globals_data);
     mem_d(code_chars_data);
     fclose(fp);
+    return true;
 }
diff --git a/gmqcc.h b/gmqcc.h
index 78c7f50..e09f175 100644
--- a/gmqcc.h
+++ b/gmqcc.h
@@ -533,7 +533,7 @@ VECTOR_PROT(char,                   code_chars     );
  * code_write -- writes out the compiled file
  * code_init  -- prepares the code file
  */
-void code_write ();
+bool code_write (const char *filename);
 void code_init  ();
 
 /*===================================================================*/
diff --git a/ir.c b/ir.c
index 8e8ffb7..e70c22c 100644
--- a/ir.c
+++ b/ir.c
@@ -1655,6 +1655,30 @@ on_error:
     return false;
 }
 
+/***********************************************************************
+ *IR Code-Generation
+ *
+ * Since the IR has the convention of putting 'write' operands
+ * at the beginning, we have to rotate the operands of instructions
+ * properly in order to generate valid QCVM code.
+ *
+ * Having destinations at a fixed position is more convenient. In QC
+ * this is *mostly* OPC,  but FTE adds at least 2 instructions which
+ * read from from OPA,  and store to OPB rather than OPC.   Which is
+ * partially the reason why the implementation of these instructions
+ * in darkplaces has been delayed for so long.
+ *
+ * Breaking conventions is annoying...
+ */
+
+bool ir_builder_generate(ir_builder *self, const char *filename)
+{
+    code_init();
+
+    code_write(filename);
+    return false;
+}
+
 /***********************************************************************
  *IR DEBUG Dump functions...
  */