Merge branch 'default' into kernigh-osx

This brings in David Given's PowerPC changes, including the addition
of the modern code generator (mcg) for PowerPC.

Resolve minor conflicts in top build.lua and util/led/main.c
This commit is contained in:
George Koehler 2016-11-28 16:20:56 -05:00
commit ecdfb61c9d
324 changed files with 13438 additions and 683 deletions

View file

@ -1,12 +1,13 @@
matrix:
include:
- os: linux
- os: osx
addons:
apt:
packages:
- ed
- openbios-ppc
- qemu-user
git:
depth: 10

17
README
View file

@ -2,7 +2,7 @@
===================================
© 1987-2005 Vrije Universiteit, Amsterdam
2016-08-02
2016-11-26
INTRODUCTION
@ -19,6 +19,7 @@ probably broken. However, what's there should be sufficient to get things
done and to evaluate how the full 6.1 release should work.
SUPPORT
=======
@ -31,10 +32,12 @@ Platforms:
pc86 produces bootable floppy disk images for 8086 PCs
linux386 produces ELF executables for PC Linux systems
linux68k produces ELF executables for m68020 Linux systems
linuxppc produces ELF executables for PowerPC Linux systems
cpm produces i80 CP/M .COM files
rpi produces Raspberry Pi GPU binaries
INSTALLATION
============
@ -55,6 +58,11 @@ Requirements:
- (optionally) ninja; if you've got this, this will be autodetected and give
you faster builds.
- (optionally) the qemu suite: if you have this installed, the build system
will detect it automatically and run the test suites for the supported
architectures. Get both the qemu-system-* platform emulators and the qemu-*
userland emulators (only works on Linux).
- about 40MB free in /tmp (or some other temporary directory).
- about 6MB in the target directory.
@ -89,6 +97,7 @@ Instructions:
The ACK should now be ready to use.
USAGE
=====
@ -155,6 +164,8 @@ There are some things you should be aware of.
interpreter and the assembler-linkers. Only some of it builds. Look for
build.lua files.
DISCLAIMER
==========
@ -177,6 +188,6 @@ You can find the mailing list on the project's web site:
Please enjoy.
David Given (dtrg on Sourceforge)
David Given (davidgiven on Github)
dg@cowlark.com
2016-08-02
2016-11-26

View file

@ -11,14 +11,25 @@ vars.plats = {
"linuxppc",
"osx386",
"osxppc",
"qemuppc",
"pc86",
"rpi",
}
vars.plats_with_tests = {
"linux386",
"linuxppc",
"qemuppc",
"pc86",
}
local plat_packages = {}
local test_packages = {}
for _, p in ipairs(vars.plats) do
plat_packages[#plat_packages+1] = "plat/"..p.."+pkg"
end
for _, p in ipairs(vars.plats_with_tests) do
test_packages[#test_packages+1] = "plat/"..p.."/tests+tests"
end
installable {
name = "ack",
@ -36,6 +47,9 @@ installable {
"util/opt+pkg",
"examples+pkg",
plat_packages
},
deps = {
test_packages
}
}

View file

@ -15,6 +15,7 @@
This is a public domain adventure and may not be sold for profit */
#include <stdlib.h>
#include <stdio.h>
#define MOXIE 13
@ -32,7 +33,9 @@ int plato_clone=3;
int blast_door=0;
int killer_count=0;
char get_char()
void character(void);
char get_char(void)
{
char c;
fflush(stdout);
@ -41,7 +44,7 @@ char get_char()
return c;
}
more()
void more(void)
{
printf("---------- More ----------");
#ifdef DEBUG
@ -55,8 +58,7 @@ more()
};
}
new_clone(resume)
int resume;
int new_clone(int resume)
{
printf("\nClone %d just died.\n",clone);
if (++clone>6)
@ -75,15 +77,14 @@ int resume;
}
}
dice_roll(number,faces)
int number, faces;
int dice_roll(int number, int faces)
{
int i,total=0;
for(i=number;i>0;i--) total+= rand()%faces+1;
return total;
}
instructions()
void instructions(void)
{
printf("\n\n\n\nWelcome to Paranoia!\n\n");
printf("HOW TO PLAY:\n\n");
@ -104,7 +105,7 @@ instructions()
printf(" If not, you can try again later.\n");
}
character()
void character(void)
{
printf("===============================================================================\n");
printf("The Character : Philo-R-DMD %d\n", clone);
@ -130,9 +131,7 @@ character()
printf("===============================================================================\n");
}
choose(a,aptr,b,bptr)
int a,b;
char *aptr, *bptr;
int choose(int a, char* aptr, int b, char* bptr)
{
printf("\nSelect \'a\' or \'b\' :\n");
printf(" a - %s.\n b - %s.\n", aptr, bptr);
@ -140,7 +139,7 @@ char *aptr, *bptr;
else return b;
}
page1()
int page1(void)
{
printf(" You wake up face down on the red and pink checked E-Z-Kleen linoleum floor.\n");
printf(" You recognise the pattern, it\'s the type preferred in the internal security\nbriefing cells. When you finally look around you, you see that you are alone\n");
@ -148,7 +147,7 @@ page1()
return 57;
}
page2()
int page2(void)
{
printf("\"Greetings,\" says the kindly Internal Security self incrimination expert who\n");
printf("meets you at the door, \"How are we doing today?\" He offers you a doughnut\n");
@ -166,7 +165,7 @@ page2()
else return new_clone(32);
}
page3()
int page3(void)
{
printf("You walk to the nearest Computer terminal and request more information about\n");
printf("Christmas. The Computer says, \"That is an A-1 ULTRAVIOLET ONLY IMMEDIATE\n");
@ -174,7 +173,7 @@ page3()
return choose(4,"You give your correct clearance",5,"You lie and claim Ultraviolet clearance");
}
page4()
int page4(void)
{
printf("\"That is classified information, Troubleshooter, thank you for your inquiry.\n");
printf(" Please report to an Internal Security self incrimination station as soon as\n");
@ -182,7 +181,7 @@ page4()
return 9;
}
page5()
int page5(void)
{
printf("The computer says, \"Troubleshooter, you are not wearing the correct colour\n");
printf("uniform. You must put on an Ultraviolet uniform immediately. I have seen to\n");
@ -193,7 +192,7 @@ page5()
return choose(6, "You open the package and put on the uniform", 7, "You finally come to your senses and run for it");
}
page6()
int page6(void)
{
printf("The uniform definitely makes you look snappy and pert. It really looks\n");
printf("impressive, and even has the new lopsided lapel fashion that you admire so\n");
@ -205,7 +204,7 @@ page6()
return 8;
}
page7()
int page7(void)
{
printf("The corridor lights dim and are replaced by red battle lamps as the Security\n");
printf("Breach alarms howl all around you. You run headlong down the corridor and\n");
@ -232,7 +231,7 @@ page7()
return 8;
}
page8()
int page8(void)
{
printf("\"Now, about your question, citizen. Christmas was an old world marketing ploy\n");
printf("to induce lower clearance citizens to purchase vast quantities of goods, thus\n");
@ -249,7 +248,7 @@ page8()
return 10;
}
page9()
int page9(void)
{
int choice;
printf("As you walk toward the tubecar that will take you to GDH7-beta, you pass one\n");
@ -262,7 +261,7 @@ page9()
return choice;
}
page10()
int page10(void)
{
int choice;
printf("You stroll briskly down the corridor, up a ladder, across an unrailed catwalk,\n");
@ -290,7 +289,7 @@ page10()
}
}
page11()
int page11(void)
{
printf("The printing on the folder says \"Experimental Self Briefing.\"\n");
printf("You open it and begin to read the following:\n");
@ -321,7 +320,7 @@ page11()
return choose(3,"You wish to ask The Computer for more information about Christmas",10,"You have decided to go directly to Goods Distribution Hall 7-beta");
}
page12()
int page12(void)
{
printf("You walk up to the door and push the button labelled \"push to exit.\"\n");
printf("Within seconds a surly looking guard shoves his face into the small plexiglass\n");
@ -333,7 +332,7 @@ page12()
return choose(11,"You sit down at the table and read the Orange packet",57,"You stare around the room some more");
}
page13()
int page13(void)
{
printf("You step into the shiny plasteel tubecar, wondering why the shape has always\n");
printf("reminded you of bullets. The car shoots forward the instant your feet touch\n");
@ -346,7 +345,7 @@ page13()
return 14;
}
page14()
int page14(void)
{
printf("You manage to pull yourself out of the tubecar and look around. Before you is\n");
printf("one of the most confusing things you have ever seen, a hallway that is\n");
@ -360,7 +359,7 @@ page14()
return 22;
}
page15()
int page15(void)
{
printf("You are set upon by a runty robot with a queer looking face and two pointy\n");
printf("rubber ears poking from beneath a tattered cap. \"Hey mister,\" it says,\n");
@ -384,7 +383,7 @@ page15()
}
}
page16()
int page16(void)
{
printf("The doll is a good buy for fifty credits; it will make a fine Christmas present\n");
printf("for one of your friends. After the sale the robot rolls away. You can use\n");
@ -395,7 +394,7 @@ page16()
return 22;
}
page17()
int page17(void)
{
int i, robot_hp=15;
printf("You whip out your laser and shoot the robot, but not before it squeezes the\n");
@ -432,7 +431,7 @@ page17()
return 22;
}
page18()
int page18(void)
{
printf("You walk to the centre of the hall, ogling like an infrared fresh from the\n");
printf("clone vats. Towering before you is the most unearthly thing you have ever\n");
@ -448,7 +447,7 @@ page18()
else return 20;
}
page19()
int page19(void)
{
printf("Quickly you regain your balance, whirl and fire your laser into the Ultraviolet\n");
printf("citizen behind you. For a moment your heart leaps to your throat, then you\n");
@ -461,7 +460,7 @@ page19()
return choose(34,"You search the body, keeping an eye open for Internal Security",22,"You run away like the cowardly dog you are");
}
page20()
int page20(void)
{
printf("Oh no! you can\'t keep your balance. You\'re falling, falling head first into\n");
printf("the Christmas beast\'s gaping maw. It\'s a valiant struggle; you think you are\n");
@ -473,7 +472,7 @@ page20()
return 22;
}
page21()
int page21(void)
{
printf("You have been wasting the leading citizens of Alpha Complex at a prodigious\n");
printf("rate. This has not gone unnoticed by the Internal Security squad at GDH7-beta.\n");
@ -482,7 +481,7 @@ page21()
return new_clone(45);
}
page22()
int page22(void)
{
printf("You are searching Goods Distribution Hall 7-beta.\n");
switch(dice_roll(1,4))
@ -494,7 +493,7 @@ page22()
}
}
page23()
int page23(void)
{
printf("You go to the nearest computer terminal and declare yourself a mutant.\n");
printf("\"A mutant, he\'s a mutant,\" yells a previously unnoticed infrared who had\n");
@ -503,7 +502,7 @@ page23()
return choose(28,"You tell them that it was really only a bad joke",24,"You want to fight it out, one against twelve");
}
page24()
int page24(void)
{
printf("Golly, I never expected someone to pick this. I haven\'t even designed\n");
printf("the 12 citizens who are going to make a sponge out of you. Tell you what,\n");
@ -511,7 +510,7 @@ page24()
return choose(28,"You change your mind and say it was only a bad joke",25,"You REALLY want to shoot it out");
}
page25()
int page25(void)
{
printf("Boy, you really can\'t take a hint!\n");
printf("They\'re closing in. Their trigger fingers are twitching, they\'re about to\n");
@ -519,7 +518,7 @@ page25()
return choose(28,"You tell them it was all just a bad joke",26,"You are going to shoot");
}
page26()
int page26(void)
{
printf("You can read the cold, sober hatred in their eyes (They really didn\'t think\n");
printf("it was funny), as they tighten the circle around you. One of them shoves a\n");
@ -529,19 +528,19 @@ page26()
return new_clone(32);
}
page27()
int page27(void)
{
/* doesn't exist. Can't happen with computer version.
designed to catch dice cheats */
}
page28()
int page28(void)
{
printf("They don\'t think it\'s funny.\n");
return 26;
}
page29()
int page29(void)
{
printf("\"Psst, hey citizen, come here. Pssfft,\" you hear. When you peer around\n");
printf("you can see someone\'s dim outline in the shadows. \"I got some information\n");
@ -559,7 +558,7 @@ page29()
}
}
page30()
int page30(void)
{
printf("You step into the shadows and offer the man a thirty credit bill. \"Just drop\n");
printf("it on the floor,\" he says. \"So you\'re looking for the Master Retailer, pssfft?\n");
@ -586,7 +585,7 @@ page30()
}
}
page31()
int page31(void)
{
printf("Like any good troubleshooter you make the least expensive decision and threaten\n");
printf("him for information. With lightning like reflexes you whip out your laser and\n");
@ -599,7 +598,7 @@ page31()
return choose(30,"You pay the 30 credits",22,"You pssfft go away stupid");
}
page32()
int page32(void)
{
printf("Finally it\'s your big chance to prove that you\'re as good a troubleshooter\n");
printf("as your previous clone. You walk briskly to mission briefing and pick up your\n");
@ -609,7 +608,7 @@ page32()
return 22;
}
page33()
int page33(void)
{
blast_door=1;
printf("You release the megabolts on the blast door, then strain against it with your\n");
@ -622,7 +621,7 @@ page33()
else return 36;
}
page34()
int page34(void)
{
printf("You have found a sealed envelope on the body. You open it and read:\n");
printf("\"WARNING: Ultraviolet Clearance ONLY. DO NOT READ.\n");
@ -650,7 +649,7 @@ page34()
return choose(46,"You rush off to the nearest computer terminal to expose the commies",22,"You wander off to look for more evidence");
}
page35()
int page35(void)
{
printf("\"Oh master,\" you hear through the gun barrel, \"where have you been? It is\n");
printf("time for the great Christmas gifting ceremony. You had better hurry and get\n");
@ -669,7 +668,7 @@ page35()
return new_clone(32);
}
page36()
int page36(void)
{
printf("\"Congratulations, troubleshooter, you have successfully found the lair of the\n");
printf("Master Retailer and completed the Troubleshooter Training Course test mission,\"\n");
@ -692,7 +691,7 @@ page36()
}
}
page37()
int page37(void)
{
printf("\"Come with me please, Troubleshooter,\" says the Green clearance technician\n");
printf("after he has dislodged your head from the cannon. \"You have been participating\n");
@ -708,7 +707,7 @@ page37()
return 38;
}
page38()
int page38(void)
{
printf("\"I am Plato-B-PHI%d, head of mutant propaganda here at the training course.\n",plato_clone);
printf("If you have any questions about mutants please come to me. Today I will be\n");
@ -725,7 +724,7 @@ page38()
return choose(39,"You volunteer for the test",40,"You duck behind a chair and hope the instructor doesn\'t notice you");
}
page39()
int page39(void)
{
printf("You bravely volunteer to test the mutant detection gun. You stand up and walk\n");
printf("down the steps to the podium, passing a very relieved Troubleshooter along the\n");
@ -743,7 +742,7 @@ page39()
return 41;
}
page40()
int page40(void)
{
printf("You breathe a sigh of relief as Plato-B-PHI picks on the other Troubleshooter.\n");
printf("\"You down here in the front,\" says the instructor pointing at the other\n");
@ -775,7 +774,7 @@ page40()
}
}
page41()
int page41(void)
{
printf("You stumble down the hallway of the Troubleshooter Training Course looking for\n");
printf("your next class. Up ahead you see one of the instructors waving to you. When\n");
@ -789,7 +788,7 @@ page41()
return choose(42,"You respond with the proper Illuminati code phrase, \"Ewige Blumenkraft\"",43,"You ignore this secret society contact");
}
page42()
int page42(void)
{
printf("\"Aha, so you are a member of the elitist Illuminati secret society,\" he says\n");
printf("loudly, \"that is most interesting.\" He turns to the large class already\n");
@ -799,7 +798,7 @@ page42()
return choose(51,"You run for it",52,"You wait for the guard");
}
page43()
int page43(void)
{
printf("You sit through a long lecture on how to recognise and infiltrate secret\n");
printf("societies, with an emphasis on mimicking secret handshakes. The basic theory,\n");
@ -815,7 +814,7 @@ page43()
return choose(44,"You go looking for a computer terminal",55,"You go to the graduation ceremony immediately");
}
page44()
int page44(void)
{
printf("You walk down to a semi-secluded part of the training course complex and\n");
printf("activate a computer terminal. \"AT YOUR SERVICE\" reads the computer screen.\n");
@ -833,7 +832,7 @@ page44()
}
}
page45()
int page45(void)
{
printf("\"Hrank Hrank,\" snorts the alarm in your living quarters. Something is up.\n");
printf("You look at the monitor above the bathroom mirror and see the message you have\n");
@ -847,7 +846,7 @@ page45()
return 10;
}
page46()
int page46(void)
{
printf("\"Why do you ask about the communists, Troubleshooter? It is not in the\n");
printf("interest of your continued survival to be asking about such topics,\" says\n");
@ -855,7 +854,7 @@ page46()
return choose(53,"You insist on talking about the communists",54,"You change the subject");
}
page47()
int page47(void)
{
printf("The Computer orders the entire Vulture squadron to terminate the Troubleshooter\n");
printf("Training Course. Unfortunately you too are terminated for possessing\n");
@ -867,7 +866,7 @@ page47()
return 0;
}
page48()
int page48(void)
{
printf("The tubecar shoots forward as you enter, slamming you back into a pile of\n");
printf("garbage. The front end rotates upward and you, the garbage and the garbage\n");
@ -877,14 +876,14 @@ page48()
return new_clone(45);
}
page49()
int page49(void)
{
printf("The instructor drags your inert body into a specimen detainment cage.\n");
printf("\"He\'ll make a good subject for tomorrow\'s mutant dissection class,\" you hear.\n");
return new_clone(32);
}
page50()
int page50(void)
{
printf("You put down the other Troubleshooter, and then wisely decide to drill a few\n");
printf("holes in the instructor as well; the only good witness is a dead witness.\n");
@ -893,27 +892,27 @@ page50()
return 41;
}
page51()
int page51(void)
{
printf("You run for it, but you don\'t run far. Three hundred strange and exotic\n");
printf("weapons turn you into a freeze dried cloud of soot.\n");
return new_clone(32);
}
page52()
int page52(void)
{
printf("You wisely wait until the instructor returns with a Blue Internal Security\n");
printf("guard. The guard leads you to an Internal Security self incrimination station.\n");
return 2;
}
page53()
int page53(void)
{
printf("You tell The Computer about:\n");
return choose(47,"The commies who have infiltrated the Troubleshooter Training Course\n and the impending People\'s Revolution",54,"Something less dangerous");
}
page54()
int page54(void)
{
printf("\"Do not try to change the subject, Troubleshooter,\" says The Computer.\n");
printf("\"It is a serious crime to ask about the communists. You will be terminated\n");
@ -927,7 +926,7 @@ page54()
else return new_clone(32);
}
page55()
int page55(void)
{
printf("You and 300 other excited graduates are marched from the lecture hall and into\n");
printf("a large auditorium for the graduation exercise. The auditorium is\n");
@ -955,7 +954,7 @@ page55()
return 0;
}
page56()
int page56(void)
{
printf("That familiar strange feeling of deja\'vu envelops you again. It is hard to\n");
printf("say, but whatever is on the other side of the door does not seem to be intended\n");
@ -963,15 +962,14 @@ page56()
return choose(33,"You open the door and step through",22,"You go looking for more information");
}
page57()
int page57(void)
{
printf("In the centre of the room is a table and a single chair. There is an Orange\n");
printf("folder on the table top, but you can\'t make out the lettering on it.\n");
return choose(11,"You sit down and read the folder",12,"You leave the room");
}
next_page(this_page)
int this_page;
int next_page(int this_page)
{
printf("\n");
switch (this_page)
@ -1038,10 +1036,11 @@ int this_page;
}
}
main()
int main(int argc, const char* argv[])
{
/* srand(time(0)); */
instructions(); more();
character(); more();
while((page=next_page(page))!=0) more();
return 0;
}

View file

@ -451,7 +451,7 @@ loadtarget = function(targetname)
target = targets[targetname]
if not target then
error(string.format("build file '%s' contains no target '%s'",
filename, targetpart))
filepart, targetpart))
end
end
@ -729,9 +729,10 @@ definerule("simplerule",
definerule("installable",
{
map = { type="targets", default={} },
deps = { type="targets", default={} },
},
function (e)
local deps = {}
local deps = filenamesof(e.deps)
local commands = {}
local srcs = {}
local outs = {}

View file

@ -226,6 +226,7 @@ definerule("cprogram",
},
function (e)
local libs = matching(filenamesof(e.deps), "%.a$")
local srcs = {}
if (#e.srcs > 0) then
for _, f in pairs(
matching(
@ -240,7 +241,7 @@ definerule("cprogram",
"%.a$"
)
) do
libs[#libs+1] = f
srcs[#srcs+1] = f
end
end
@ -248,7 +249,7 @@ definerule("cprogram",
name = e.name,
cwd = e.cwd,
deps = e.deps,
ins = libs,
ins = { srcs, libs },
outleaves = { e.name },
commands = e.commands,
}

View file

@ -702,6 +702,7 @@ static int Pgetpid(lua_State *L) /** getpid([options]) */
}
#if 0
static int Phostid(lua_State *L) /** hostid() */
{
char b[32];
@ -709,6 +710,7 @@ static int Phostid(lua_State *L) /** hostid() */
lua_pushstring(L, b);
return 1;
}
#endif
static int Pttyname(lua_State *L) /** ttyname([fd]) */
@ -1060,7 +1062,7 @@ static const luaL_reg R[] =
{"getpasswd", Pgetpasswd},
{"getpid", Pgetpid},
{"glob", Pglob},
{"hostid", Phostid},
//{"hostid", Phostid},
{"kill", Pkill},
{"link", Plink},
{"mkdir", Pmkdir},

View file

@ -1,6 +1,9 @@
#include <stdlib.h>
#include <stdio.h>
int _errsym;
int _erlsym;
/* error takes an error value in the range of 0-255 */
/* and generates a trap */
@ -52,9 +55,6 @@ char *errortable[255]={
error(index)
int index;
{
extern int _errsym;
extern int _erlsym;
_setline();
if( index<0 || index >40 )
printf("LINE %d:ERROR %d: Unprintable error\n",_erlsym,index);

View file

@ -31,6 +31,7 @@ int ltype,rtype;
void
conversion(oldtype,newtype)
int oldtype,newtype;
{
@ -71,6 +72,7 @@ int oldtype,newtype;
void
extraconvert(oldtype,newtype,topstack)
int oldtype,newtype,topstack;
{
@ -509,6 +511,7 @@ endarrayload()
void
loadarray(type)
int type;
{

View file

@ -617,11 +617,7 @@ prologcode()
C_df_dnam("_iomode");
C_rom_scon("O",(arith)2);
C_exa_dnam("_errsym");
C_df_dnam("_errsym");
C_bss_cst((arith)BEMINTSIZE,(arith)0,1);
C_exa_dnam("_erlsym");
C_df_dnam("_erlsym");
C_bss_cst((arith)BEMINTSIZE,(arith)0,1);
}

View file

@ -68,6 +68,7 @@ char *str;
void
dcltype(s)
Symbol *s;
{

View file

@ -16,6 +16,7 @@ int errorcnt;
void
warning(str)
char *str;
{

View file

@ -52,6 +52,8 @@ extern int lint_skip_comment;
static struct token LexStack[MAX_LL_DEPTH];
static LexSP = 0;
void skipcomment();
/* In PushLex() the actions are taken in order to initialise or
re-initialise the lexical scanner.
E.g. at the invocation of a sub-parser that uses LLlex(), the
@ -442,6 +444,7 @@ garbage:
}
#ifndef NOPP
void
skipcomment()
{
/* The last character read has been the '*' of '/_*'. The

View file

@ -30,6 +30,7 @@ extern char options[];
extern arith flt_flt2arith();
extern label code_string();
void
arithbalance(e1p, oper, e2p) /* 3.1.2.5 */
register struct expr **e1p, **e2p;
int oper;
@ -523,6 +524,7 @@ opnd2logical(expp, oper)
}
}
void
opnd2test(expp, oper)
register struct expr **expp;
{
@ -548,6 +550,7 @@ opnd2test(expp, oper)
ch3bin(expp, NOTEQUAL, intexpr((arith)0, INT));
}
void
any2opnd(expp, oper)
register struct expr **expp;
{

View file

@ -23,11 +23,14 @@ extern char options[];
extern char *symbol2str();
extern struct type *qualifier_type();
void ch3cast();
/* Most expression-handling routines have a pointer to a
(struct type *) as first parameter. The object under the pointer
gets updated in the process.
*/
void
ch3sel(expp, oper, idf)
struct expr **expp;
struct idf *idf;
@ -169,6 +172,7 @@ ch3incr(expp, oper)
ch3asgn(expp, oper, intexpr((arith)1, INT));
}
void
ch3cast(expp, oper, tp)
register struct expr **expp;
register struct type *tp;

View file

@ -19,6 +19,8 @@
extern char options[];
extern char *symbol2str();
void pntminuspnt();
/* This chapter asks for the repeated application of code to handle
an operation that may be executed at compile time or at run time,
depending on the constancy of the operands.
@ -32,6 +34,7 @@ extern char *symbol2str();
#define commutative_binop(expp, oper, expr) mk_binop(expp, oper, expr, 1)
#define non_commutative_relop(expp, oper, expr) mk_binop(expp, oper, expr, 1)
void
ch3bin(expp, oper, expr)
register struct expr **expp;
struct expr *expr;
@ -292,6 +295,7 @@ ch3bin(expp, oper, expr)
}
}
void
pntminuspnt(expp, oper, expr)
register struct expr **expp, *expr;
{

View file

@ -64,6 +64,8 @@ extern char options[];
extern char *symbol2str();
extern char *source;
void loc_init();
#ifndef LINT
init_code(dst_file)
char *dst_file;
@ -415,6 +417,7 @@ do_return_expr(expr)
return_expr_occurred = 1;
}
void
code_declaration(idf, expr, lvl, sc)
register struct idf *idf; /* idf to be declared */
struct expr *expr; /* initialisation; NULL if absent */
@ -527,6 +530,7 @@ code_declaration(idf, expr, lvl, sc)
}
}
void
loc_init(expr, id)
struct expr *expr;
struct idf *id;
@ -721,6 +725,7 @@ code_break()
it generates a branch instruction to the continue label of the
innermost statement in which continue has a meaning.
*/
void
code_continue()
{
register struct stmt_block *stmt_block = stmt_stack;

View file

@ -34,6 +34,9 @@ char ifstack[IFDEPTH]; /* if-stack: the content of an entry is */
int nestlevel = -1;
void macro_def();
void do_define();
struct idf *
GetIdentifier(skiponerr)
int skiponerr; /* skip the rest of the line on error */
@ -145,6 +148,7 @@ domacro()
int lint_skip_comment;
#endif
void
skip_block(to_endif)
int to_endif;
{
@ -347,6 +351,7 @@ do_include()
}
}
void
do_define()
{
/* do_define() interprets a #define control line.
@ -574,6 +579,7 @@ getparams(buf, parbuf)
/*NOTREACHED*/
}
void
macro_def(id, text, nformals, length, flags)
register struct idf *id;
char *text;

View file

@ -57,7 +57,7 @@ extern char loptions[];
expression, whereas other errors use the information in the token.
*/
static _error();
static void _error();
#if __STDC__
/*VARARGS*/
@ -521,7 +521,7 @@ fatal(va_alist) /* fmt, args */
}
#endif
static
static void
_error(class, fn, ln, fmt, ap)
int class;
char *fn;

View file

@ -37,6 +37,9 @@ arith NewLocal(); /* util.c */
#define LocalPtrVar() NewLocal(pointer_size, pointer_align, reg_pointer, REGISTER)
extern int err_occurred; /* error.c */
void store_val();
void load_val();
/* EVAL() is the main expression-tree evaluator, which turns
any legal expression tree into EM code. parameters.h:
@ -63,6 +66,7 @@ extern int err_occurred; /* error.c */
labels, in case they are specified (i.e. are non-zero)
*/
void
EVAL(expr, val, code, true_label, false_label)
register struct expr *expr;
int val, code;
@ -836,6 +840,7 @@ ptr_add(size)
- into a local static variable
- absolute addressing
*/
void
store_val(vl, tp)
register struct value *vl;
register struct type *tp;
@ -907,6 +912,7 @@ store_val(vl, tp)
- static variable
- local variable
*/
void
load_val(expr, rlval)
register struct expr *expr; /* expression containing the value */
int rlval; /* generate either LVAL or RVAL */

View file

@ -369,6 +369,7 @@ new_oper(tp, e1, oper, e2)
return expr;
}
void
chk_cst_expr(expp)
struct expr **expp;
{

View file

@ -37,6 +37,8 @@ extern char *symbol2str();
#include <idf_pkg.body>
void global_redecl();
struct idf *
gen_idf()
{
@ -248,6 +250,7 @@ declare_idf(ds, dc, lvl)
}
}
int
actual_declaration(sc, tp)
int sc;
struct type *tp;
@ -269,6 +272,7 @@ actual_declaration(sc, tp)
return 1;
}
void
global_redecl(idf, new_sc, tp)
register struct idf *idf;
struct type *tp;
@ -393,6 +397,7 @@ declare_params(dc)
}
}
void
idf_initialized(idf)
register struct idf *idf;
{
@ -429,6 +434,7 @@ declare_enum(tp, idf, l)
idf->id_def->df_address = l;
}
void
check_formals(idf, dc)
struct idf *idf;
struct declarator *dc;

View file

@ -7,6 +7,7 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "parameters.h"
#ifndef NOPP
@ -44,7 +45,7 @@ init_pp()
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
long clock, sys_time();
time_t clock;
static char dbuf[30];
static char tbuf[30];
struct tm *tp;
@ -70,7 +71,7 @@ init_pp()
/* Initialize __LINE__, __FILE__, __DATE__, __TIME__,
and __STDC__ macro definitions.
*/
clock = sys_time();
clock = time(NULL);
tp = localtime(&clock);
/* __DATE__ */

View file

@ -46,6 +46,11 @@ static int pack_level;
struct type **gen_tphead(), **gen_tpmiddle();
struct sdef *gen_align_to_next();
struct e_stack *p_stack;
void pad();
void gen_simple_exp();
void gen_tpcheck();
}
/* initial_value recursively guides the initialisation expression.
@ -122,6 +127,7 @@ initial_value_list(register struct type **tpp; struct expr **expp;)
;
{
void
gen_tpcheck(tpp)
struct type **tpp;
{
@ -147,6 +153,7 @@ gen_tpcheck(tpp)
}
}
void
gen_simple_exp(tpp, expp)
struct type **tpp;
struct expr **expp;
@ -465,6 +472,7 @@ check_and_pad(expp, tpp)
/* pad() fills an element of type tp with zeroes.
If the element is an aggregate, pad() is called recursively.
*/
void
pad(tpx)
struct type *tpx;
{

View file

@ -46,6 +46,8 @@ struct sp_id special_ids[] = {
{0, 0}
};
void dependency();
#ifndef NOCROSS
arith
short_size = SZ_SHORT,
@ -181,6 +183,7 @@ char *s;
}
}
void
dependency(s, source)
char *s, *source;
{

View file

@ -26,6 +26,7 @@
extern char options[];
void
check_for_void(pl)
register struct proto *pl;
{
@ -261,6 +262,7 @@ declare_protos(dc)
}
void
update_proto(tp, otp)
register struct type *tp, *otp;
{
@ -312,6 +314,7 @@ update_proto(tp, otp)
/* struct/union and enum tags can be declared inside prototypes
* remove them from the symbol-table
*/
void
remove_proto_tag(tp)
struct type *tp;
{
@ -380,6 +383,7 @@ remove_proto_idfs(pl)
}
}
void
call_proto(expp)
register struct expr **expp;
{

View file

@ -26,6 +26,10 @@ extern int InputLevel;
struct repl *ReplaceList; /* list of currently active macros */
extern char *strcat(), *strcpy();
void macro2buffer();
void getactuals();
void expand_defined();
int
replace(idf)
register struct idf *idf;
@ -172,6 +176,7 @@ expand_macro(repl, idf)
return 1;
}
void
expand_defined(repl)
register struct repl *repl;
{
@ -211,6 +216,7 @@ newarg(args)
args->a_rawptr = args->a_rawbuf = Malloc(args->a_rawsize = ARGBUF);
}
void
getactuals(repl, idf)
struct repl *repl;
register struct idf *idf;
@ -529,6 +535,7 @@ macro_func(idef)
}
}
void
macro2buffer(repl, idf, args)
register struct repl *repl;
register struct idf *idf;

View file

@ -72,7 +72,7 @@ adds_db_str(s)
while (*s) addc_db_str(*s++);
}
static
static void
stb_type(tp)
register struct type *tp;
{

View file

@ -57,6 +57,7 @@ stack_level() {
#endif /* LINT */
}
void
stack_idf(idf, stl)
struct idf *idf;
register struct stack_level *stl;

View file

@ -159,6 +159,7 @@ code_endswitch()
unstack_stmt();
}
void
code_case(expr)
struct expr *expr;
{
@ -227,6 +228,7 @@ code_case(expr)
}
}
void
code_default()
{
register struct switch_hdr *sh = switch_stack;

View file

@ -163,6 +163,7 @@ LocalFinish()
#endif
}
void
RegisterAccount(offset, size, regtype, sc)
arith offset, size;
{

View file

@ -35,6 +35,8 @@ extern arith char_constant();
#define FLG_ESEEN 0x01 /* possibly a floating point number */
#define FLG_DOTSEEN 0x02 /* certainly a floating point number */
void skipcomment();
int
LLlex()
{
@ -325,6 +327,7 @@ garbage:
/*NOTREACHED*/
}
void
skipcomment()
{
/* The last character read has been the '*' of '/_*'. The

View file

@ -32,6 +32,9 @@ int svnestlevel[30] = {-1};
int nestcount;
extern int do_preprocess;
void macro_def();
void do_define();
char *
GetIdentifier(skiponerr)
int skiponerr; /* skip the rest of the line on error */
@ -148,6 +151,7 @@ domacro()
}
}
void
skip_block(to_endif)
int to_endif;
{
@ -327,6 +331,7 @@ do_include()
}
}
void
do_define()
{
/* do_define() interprets a #define control line.
@ -566,6 +571,7 @@ getparams(buf, parbuf)
/*NOTREACHED*/
}
void
macro_def(id, text, nformals, length, flags)
register struct idf *id;
char *text;

View file

@ -7,6 +7,7 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "system.h"
#include "alloc.h"
#include "time.h"
@ -42,7 +43,7 @@ init_pp()
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
long clock, sys_time();
time_t clock;
static char dbuf[30];
static char tbuf[30];
struct tm *tp;
@ -68,7 +69,7 @@ init_pp()
/* Initialize __LINE__, __FILE__, __DATE__, __TIME__,
and __STDC__ macro definitions.
*/
clock = sys_time();
clock = time(NULL);
tp = localtime(&clock);
/* __DATE__ */

View file

@ -32,6 +32,8 @@ char *prog_name;
extern char **inctable;
extern int inc_max, inc_total;
void dependency();
main(argc, argv)
char *argv[];
{
@ -140,6 +142,7 @@ add_dependency(s)
}
}
void
dependency(s, source)
char *s, *source;
{

View file

@ -102,6 +102,7 @@ do_pragma()
char Xbuf[256];
void
preprocess(fn)
char *fn;
{

View file

@ -26,6 +26,10 @@ extern char *strcat();
extern int InputLevel;
struct repl *ReplaceList; /* list of currently active macros */
void expand_defined();
void getactuals();
void macro2buffer();
int
replace(idf)
register struct idf *idf;
@ -165,6 +169,7 @@ expand_macro(repl, idf)
return 1;
}
void
expand_defined(repl)
register struct repl *repl;
{
@ -208,6 +213,7 @@ newarg(args)
args->a_rawptr = args->a_rawbuf = Malloc((unsigned)(args->a_rawsize = ARGBUF));
}
void
getactuals(repl, idf)
struct repl *repl;
register struct idf *idf;
@ -522,6 +528,7 @@ macro_func(idef)
}
}
void
macro2buffer(repl, idf, args)
register struct repl *repl;
register struct idf *idf;

View file

@ -0,0 +1,23 @@
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
void* calloc(size_t nmemb, size_t size)
{
size_t bytes = nmemb * size;
void* ptr;
/* Test for overflow.
* See http://stackoverflow.com/questions/1815367/multiplication-of-large-numbers-how-to-catch-overflow
*/
if ((nmemb == 0) || (size == 0) || (nmemb > (SIZE_MAX / size)))
return NULL;
ptr = malloc(bytes);
if (!ptr)
return NULL;
memset(ptr, 0, bytes);
return ptr;
}

View file

@ -180,6 +180,7 @@ getch()
return ch;
}
void
CheckForLineDirective()
{
register int ch = getch();

View file

@ -54,6 +54,9 @@ struct case_entry {
arith ce_low, ce_up; /* lower and upper bound of range */
};
void AddCases();
void AddOneCase();
/* STATICALLOCDEF "case_entry" 20 */
/* The constant DENSITY determines when CSA and when CSB instructions
@ -237,6 +240,7 @@ FreeSh(sh)
free_switch_hdr(sh);
}
void
AddCases(sh, node, lbl)
struct switch_hdr *sh;
register t_node *node;
@ -264,6 +268,7 @@ AddCases(sh, node, lbl)
AddOneCase(sh, node, node, lbl);
}
void
AddOneCase(sh, lnode, rnode, lbl)
register struct switch_hdr *sh;
t_node *lnode, *rnode;

View file

@ -53,6 +53,7 @@ df_error(nd, mess, edf)
else node_error(nd, mess);
}
void
MkCoercion(pnd, tp)
t_node **pnd;
register t_type *tp;

View file

@ -37,6 +37,10 @@ extern char options[];
extern t_desig null_desig;
int fp_used;
void RangeCheck();
void CodeParameters();
void CodeCall();
CodeConst(cst, size)
arith cst;
int size;
@ -55,6 +59,7 @@ CodeConst(cst, size)
}
}
void
CodeString(nd)
register t_node *nd;
{
@ -288,6 +293,7 @@ CodeCoercion(t1, t2)
}
}
void
CodeCall(nd)
register t_node *nd;
{
@ -355,6 +361,7 @@ CodeCall(nd)
DoLineno(nd);
}
void
CodeParameters(param, arg)
t_param *param;
register t_node *arg;
@ -672,6 +679,7 @@ needs_rangecheck(tpl, tpr)
return 0;
}
void
RangeCheck(tpl, tpr)
register t_type *tpl, *tpr;
{

View file

@ -45,6 +45,8 @@ arith min_int[] = { 0L, -128L, -32768L, 0L, -2147483647L-1 };
extern char options[];
void CutSize();
overflow(expp)
t_node *expp;
{
@ -160,6 +162,7 @@ divide(pdiv, prem)
#endif
}
void
cstibin(expp)
t_node **expp;
{
@ -351,6 +354,7 @@ cstfbin(expp)
CutSize(exp);
}
void
cstubin(expp)
t_node **expp;
{
@ -457,6 +461,7 @@ cstubin(expp)
CutSize(exp);
}
void
cstset(expp)
t_node **expp;
{
@ -648,6 +653,7 @@ cstcall(expp, call)
}
}
void
CutSize(expr)
register t_node *expr;
{

View file

@ -533,6 +533,7 @@ CodeFieldDesig(df, ds)
}
}
void
CodeVarDesig(df, ds)
register t_def *df;
register t_desig *ds;

View file

@ -247,6 +247,7 @@ EnterParamList(ppr, Idlist, type, VARp, off)
STATIC t_def *DoImport();
void
ImportEffects(idef, scope, flag)
register t_def *idef;
t_scope *scope;
@ -481,6 +482,7 @@ CheckForImports(df)
}
}
void
EnterFromImportList(idlist, FromDef, FromId)
register t_node *idlist;
register t_def *FromDef;

View file

@ -61,6 +61,8 @@ extern char *symbol2str();
node, whereas other errors use the information in the token.
*/
void _error();
#if __STDC__
#ifdef DEBUG
/*VARARGS*/
@ -318,6 +320,7 @@ crash(va_alist)
}
#endif
void
_error(class, node, fmt, ap, warn_class)
int class;
t_node *node;

View file

@ -81,6 +81,7 @@ dot2leaf(class)
return nd;
}
void
FreeNode(nd)
register t_node *nd;
{

View file

@ -71,7 +71,7 @@ adds_db_str(s)
while (*s) addc_db_str(*s++);
}
static
static void
stb_type(tp, assign_num)
register t_type *tp;
{

View file

@ -74,6 +74,8 @@ t_type
*std_type,
*error_type;
void ArraySizes();
t_type *
construct_type(fund, tp)
int fund;
@ -576,6 +578,7 @@ ArrayElSize(tp)
}
}
void
ArraySizes(tp)
register t_type *tp;
{

View file

@ -64,7 +64,7 @@ static int WalkDef();
static int stabdef();
#endif
static int MkCalls();
static int UseWarnings();
static void UseWarnings();
#define NO_EXIT_LABEL ((label) 0)
#define RETURN_LABEL ((label) 1)
@ -72,6 +72,8 @@ static int UseWarnings();
#define REACH_FLAG 1
#define EXIT_FLAG 2
void DoAssign();
int
LblWalkNode(lbl, nd, exit, reach)
label lbl, exit;
@ -995,6 +997,7 @@ node_warning(nd, W_OLDFASHIONED, "compatibility required in FOR statement");
return 1;
}
void
DoAssign(nd)
register t_node *nd;
{
@ -1057,7 +1060,7 @@ RegisterMessage(df)
}
}
static
static void
df_warning(nd, df, warning)
t_node *nd;
t_def *df;
@ -1080,7 +1083,7 @@ df_warning(nd, df, warning)
}
}
static
static void
UseWarnings(df)
register t_def *df;
{

View file

@ -120,7 +120,7 @@ CommentOptions()
}
STATIC
STATIC void
SkipComment()
{
/* Skip ISO-Pascal comments (* ... *) or { ... }.
@ -216,6 +216,7 @@ register int delim;
static char *s_error = "illegal line directive";
void
CheckForLineDirective()
{
register int ch;

View file

@ -47,6 +47,7 @@ MarkDef(nd, flags, on)
}
}
void
AssertStat(expp, line)
register struct node *expp;
unsigned short line;
@ -69,6 +70,7 @@ AssertStat(expp, line)
}
}
void
AssignStat(left, right)
register struct node *left, *right;
{
@ -131,6 +133,7 @@ AssignStat(left, right)
FreeNode(right);
}
void
ProcStat(nd)
register struct node *nd;
{
@ -142,6 +145,7 @@ ProcStat(nd)
}
}
void
ChkForStat(nd)
register struct node *nd;
{
@ -202,6 +206,7 @@ ChkForStat(nd)
return;
}
void
EndForStat(nd)
register struct node *nd;
{
@ -283,6 +288,7 @@ CodeEndFor(nd, stepsize, l1, l2, tmp2)
C_asp(int_size);
}
void
WithStat(nd)
struct node *nd;
{

View file

@ -40,6 +40,7 @@ struct case_entry {
*/
#define compact(nr, low, up) (nr != 0 && (up - low) / nr <= DENSITY)
void
CaseExpr(nd)
struct node *nd;
{
@ -62,6 +63,7 @@ CaseExpr(nd)
}
}
void
CaseEnd(nd, exit_label)
struct node *nd;
label exit_label;

View file

@ -1183,13 +1183,6 @@ ChkStandard(expp,left)
expp->nd_type = NULLTYPE;
break;
case R_MARK:
case R_RELEASE:
if( !(left = getarg(&arg, T_POINTER, 1, name, NULLTYPE)) )
return 0;
expp->nd_type = NULLTYPE;
break;
case R_HALT:
if( !arg->nd_right ) /* insert 0 parameter */
arg->nd_right = ZeroParam();

View file

@ -24,6 +24,11 @@
int fp_used;
void Long2Int();
void Int2Long();
void genrck();
void CodeCall();
CodeFil()
{
if ( !options['L'] )
@ -791,6 +796,7 @@ CodePString(nd, tp)
C_loi(tp->tp_size);
}
void
CodeCall(nd)
register struct node *nd;
{
@ -1070,16 +1076,6 @@ CodeStd(nd)
C_asp(pointer_size + word_size);
break;
case R_MARK:
case R_RELEASE:
CodeDAddress(left);
if( req == R_MARK )
C_cal("_sav");
else
C_cal("_rst");
C_asp(pointer_size);
break;
case R_HALT:
if( left )
CodePExpr(left);
@ -1095,6 +1091,7 @@ CodeStd(nd)
}
}
void
Long2Int()
{
/* convert a long to integer */
@ -1106,6 +1103,7 @@ Long2Int()
C_cii();
}
void
Int2Long()
{
/* convert integer to long */
@ -1160,6 +1158,7 @@ RangeCheck(tpl, tpr)
}
}
void
genrck(tp)
register struct type *tp;
{

View file

@ -66,6 +66,7 @@ cstunary(expp)
expp->nd_right = NULLNODE;
}
void
cstbin(expp)
register struct node *expp;
{
@ -195,6 +196,7 @@ cstbin(expp)
expp->nd_left = expp->nd_right = NULLNODE;
}
void
cstset(expp)
register struct node *expp;
{

View file

@ -116,6 +116,7 @@ define(id, scope, kind)
return MkDef(id, scope, kind);
}
void
DoDirective(directive, nd, tp, scl, function)
struct idf *directive;
struct node *nd;

View file

@ -26,6 +26,7 @@
struct desig InitDesig = {DSG_INIT, 0, 0, NULLDEF, 0};
struct withdesig *WithDesigs;
void CodeValue();
STATIC int
properly(ds, size, al)
@ -71,6 +72,7 @@ CodeCopy(lhs, rhs, sz, psize)
C_sti(sz);
}
void
CodeMove(rhs, left, rtp)
register struct desig *rhs;
register struct node *left;
@ -150,6 +152,7 @@ CodeMove(rhs, left, rtp)
}
}
void
CodeValue(ds, tp)
register struct desig *ds;
register struct type *tp;
@ -366,6 +369,7 @@ CodeFieldDesig(df, ds)
ds->dsg_packed = df->fld_flags & F_PACKED;
}
void
CodeVarDesig(df, ds)
register struct def *df;
register struct desig *ds;

View file

@ -39,6 +39,8 @@ int err_occurred;
extern char *symbol2str();
void _error();
/* There are three general error-message functions:
lexerror() lexical and pre-processor error messages
error() syntactic and pre-processor messagese
@ -304,6 +306,7 @@ crash(va_alist)
}
#endif
void
_error(class, node, fmt, ap)
int class;
struct node *node;

View file

@ -12,6 +12,8 @@
#include "scope.h"
#include "type.h"
void CodeLabel();
DeclLabel(nd)
struct node *nd;
@ -103,6 +105,7 @@ TstLabel(nd, Slevel)
CodeLabel(df, 1);
}
void
DefLabel(nd, Slevel)
register struct node *nd;
{
@ -139,6 +142,7 @@ DefLabel(nd, Slevel)
}
}
void
CodeLabel(df, local)
register struct def *df;
{

View file

@ -189,10 +189,6 @@ AddRequired()
/* DYNAMIC ALLOCATION PROCEDURES */
(void) Enter("new", D_PROCEDURE, std_type, R_NEW);
(void) Enter("dispose", D_PROCEDURE, std_type, R_DISPOSE);
if( !options['s'] ) {
(void) Enter("mark", D_PROCEDURE, std_type, R_MARK);
(void) Enter("release", D_PROCEDURE, std_type, R_RELEASE);
}
/* MISCELLANEOUS PROCEDURE(S) */
if( !options['s'] )

View file

@ -42,6 +42,7 @@ MkLeaf(class, token)
return nd;
}
void
FreeNode(nd)
register struct node *nd;
{

View file

@ -15,6 +15,8 @@ static int inpflag = 0; /* input mentioned in heading ? */
static int outpflag = 0; /* output mentioned in heading ? */
static label extfl_label; /* label of array of file pointers */
void make_extfl_args();
set_inp()
{
inpflag = 1;
@ -25,6 +27,7 @@ set_outp()
outpflag = 1;
}
void
make_extfl()
{
if( err_occurred ) return;
@ -54,6 +57,7 @@ make_extfl()
make_extfl_args( GlobalScope->sc_def );
}
void
make_extfl_args(df)
register struct def *df;
{

View file

@ -19,6 +19,12 @@
extern char *sprint();
void CodeRead();
void CodeReadln();
void CodeWrite();
void CodeWriteln();
void
ChkRead(arg)
register struct node *arg;
{
@ -86,6 +92,7 @@ ChkRead(arg)
}
}
void
ChkReadln(arg)
register struct node *arg;
{
@ -142,6 +149,7 @@ ChkReadln(arg)
CodeReadln(file);
}
void
ChkWrite(arg)
register struct node *arg;
{
@ -183,6 +191,7 @@ ChkWrite(arg)
}
}
void
ChkWriteln(arg)
register struct node *arg;
{
@ -318,6 +327,7 @@ ChkStdInOut(name, st_out)
return nd;
}
void
CodeRead(file, arg)
register struct node *file, *arg;
{
@ -376,6 +386,7 @@ CodeRead(file, arg)
}
}
void
CodeReadln(file)
struct node *file;
{
@ -386,6 +397,7 @@ CodeReadln(file)
C_asp(pointer_size);
}
void
CodeWrite(file, arg)
register struct node *file, *arg;
{
@ -472,6 +484,7 @@ CodeWrite(file, arg)
}
}
void
CodeWriteln(file)
register struct node *file;
{

View file

@ -1,48 +1,51 @@
/* REQUIRED PROCEDURES AND FUNCTIONS */
/* PROCEDURES */
/* FILE HANDLING */
#define R_REWRITE 1
#define R_PUT 2
#define R_RESET 3
#define R_GET 4
#define R_PAGE 5
enum
{
R__UNUSED = 0,
/* DYNAMIC ALLOCATION */
#define R_NEW 6
#define R_DISPOSE 7
#define R_MARK 8
#define R_RELEASE 9
/* PROCEDURES */
/* FILE HANDLING */
R_REWRITE,
R_PUT,
R_RESET,
R_GET,
R_PAGE,
/* MISCELLANEOUS PROCEDURE(S) */
#define R_HALT 10
/* DYNAMIC ALLOCATION */
R_NEW,
R_DISPOSE,
/* TRANSFER */
#define R_PACK 11
#define R_UNPACK 12
/* MISCELLANEOUS PROCEDURE(S) */
R_HALT,
/* FUNCTIONS */
/* ARITHMETIC */
#define R_ABS 13
#define R_SQR 14
#define R_SIN 15
#define R_COS 16
#define R_EXP 17
#define R_LN 18
#define R_SQRT 19
#define R_ARCTAN 20
/* TRANSFER */
R_PACK,
R_UNPACK,
/* TRANSFER */
#define R_TRUNC 21
#define R_ROUND 22
/* FUNCTIONS */
/* ARITHMETIC */
R_ABS,
R_SQR,
R_SIN,
R_COS,
R_EXP,
R_LN,
R_SQRT,
R_ARCTAN,
/* ORDINAL */
#define R_ORD 23
#define R_CHR 24
#define R_SUCC 25
#define R_PRED 26
/* TRANSFER */
R_TRUNC,
R_ROUND,
/* BOOLEAN */
#define R_ODD 27
#define R_EOF 28
#define R_EOLN 29
/* ORDINAL */
R_ORD,
R_CHR,
R_SUCC,
R_PRED,
/* BOOLEAN */
R_ODD,
R_EOF,
R_EOLN,
};

View file

@ -71,7 +71,7 @@ adds_db_str(s)
while (*s) addc_db_str(*s++);
}
static
static void
stb_type(tp, assign_num)
register struct type *tp;
{
@ -247,6 +247,7 @@ stb_addtp(s, tp)
(arith) 0);
}
void
stb_string(df, kind)
register struct def *df;
long kind;

View file

@ -51,6 +51,8 @@ struct type
*void_type,
*error_type;
void ArraySizes();
CheckTypeSizes()
{
/* first, do some checking
@ -442,6 +444,7 @@ ArrayElSize(tp, packed)
return algn;
}
void
ArraySizes(tp)
register struct type *tp;
{
@ -489,6 +492,7 @@ ArraySizes(tp)
C_rom_cst(tp->arr_elsize);
}
void
FreeForward(for_type)
register struct forwtype *for_type;
{

View file

@ -11,7 +11,6 @@ for _, plat in ipairs(vars.plats) do
"./fif.e",
"./gto.e",
"./hol0.e",
"./sav.e",
"./sig.e",
"./trap.e",
"./trp.e",

View file

@ -1,101 +0,0 @@
/*
* File: - dis.c
*
* dispose() built in standard procedure in Pascal (6.6.5.3)
*
* Re-implementation of storage allocator for Ack Pascal compiler
* under Linux, and other UNIX-like systems.
*
* Written by Erik Backerud, 2010-10-01
*
* Original copyright and author info below:
*/
/* $Id$ */
/*
* (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
*
* This product is part of the Amsterdam Compiler Kit.
*
* Permission to use, sell, duplicate or disclose this software must be
* obtained in writing. Requests for such permissions may be sent to
*
* Dr. Andrew S. Tanenbaum
* Wiskundig Seminarium
* Vrije Universiteit
* Postbox 7161
* 1007 MC Amsterdam
* The Netherlands
*
*/
/* Author: J.W. Stevenson */
#include <pc_err.h>
#define assert() /* nothing */
/*
* use a singly linked list of free blocks.
*/
struct adm {
struct adm *next;
int size;
};
struct adm *freep = 0; /* first element on free list */
extern void _trp(int);
/*
* Dispose
* Called with two arguments:
* n the size of the block to be freed, in bytes,
* pp address of pointer to data.
*/
void
_dis(int n, struct adm **pp)
{
struct adm *block; /* the block of data being freed (inc. header) */
struct adm *p, *q;
if (*pp == 0) {
_trp(EFREE);
}
block = *pp - 1;
if (freep == 0) {
freep = block;
block->next = 0;
} else {
q = 0; /* trail one behind */
for (p = freep; p < block; p = p->next) {
if (p == 0) { /* We reached the end of the free list. */
break;
}
q = p;
/* check if block is contained in the free block p */
if (p+p->size > block) {
_trp(EFREE);
}
}
if (p == block) { /* this block already freed */
_trp(EFREE);
}
if (q == 0) { /* block is first */
freep = block;
block->next = p;
} else {
q->next = block;
}
block->next = p;
/* merge with successor on free list? */
if (block + block->size == p) {
block->size = block->size + p->size;
block->next = p->next;
}
/* merge with preceding block on free list? */
if (q != 0 && q+q->size == block) {
q->size = q->size + block->size;
q->next = block->next;
}
}
} /* _dis */

View file

@ -1,120 +1,20 @@
/*
* File: - new.c
*
* new() built in standard procedure in Pascal (6.6.5.3)
*
* Re-implementation of storage allocator for Ack Pascal compiler
* under Linux, and other UNIX-like systems.
*
* Written by Erik Backerud, 2010-10-01
*
* Original copyright and author info below:
*/
/* $Id$ */
/*
* (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
*
* This product is part of the Amsterdam Compiler Kit.
*
* Permission to use, sell, duplicate or disclose this software must be
* obtained in writing. Requests for such permissions may be sent to
*
* Dr. Andrew S. Tanenbaum
* Wiskundig Seminarium
* Vrije Universiteit
* Postbox 7161
* 1007 MC Amsterdam
* The Netherlands
*
*/
/* Author: J.W. Stevenson */
#include <stdlib.h>
#include <em_abs.h>
#include <pc_err.h>
#define assert(x) /* nothing */
#define UNDEF 0x8000
#define NALLOC (1024) /* request this many units from OS */
/*
* use a singly linked list of free blocks.
*/
struct adm {
struct adm *next;
int size;
};
extern struct adm *freep;
extern void _trp(int); /* called on error */
extern void _dis(int, struct adm **);
/*
* Helper function to request 'nu' units of memory from the OS.
* A storage unit is sizeof(struct adm). Typically 8 bytes
* on a 32-bit machine like i386 etc.
*/
static struct adm *
morecore(unsigned nu)
void _new(int n, void** ptr)
{
char *cp, *sbrk(int);
struct adm *up;
if (nu < NALLOC)
nu = NALLOC;
cp = sbrk(nu * sizeof(struct adm));
if (cp == (char *) -1) /* no space at all */
return 0;
up = (struct adm*) cp;
up->size = nu;
up = up + 1;
_dis((nu - 1) * sizeof(struct adm), &up);
return freep;
} /* morecore */
/*
* Dispose
* Called with two arguments:
* n the size of the block to be freed, in bytes,
* pp address of pointer to data.
*/
void
_new(int n, struct adm **pp)
{
int nunits; /* the unit of storage is sizeof(struct adm) */
struct adm *p,*q;
/* round up size of request */
nunits = (n + sizeof(struct adm) - 1) / sizeof(struct adm) + 1;
q = 0;
for (p = freep; ; p = p->next) {
if (p == 0) {
p = morecore(nunits);
if (p == 0)
void* p = malloc(n);
if (!p)
_trp(EHEAP);
q = 0;
}
if (p->size >= nunits) {
if (p->size == nunits) { /* exact fit */
if (q == 0) { /* first element on free list. */
freep = p->next;
} else {
q->next = p->next;
}
} else { /* allocate tail end */
q = p;
q->size = q->size - nunits;
p = q + q->size;
p->next = 0;
p->size = nunits;
}
break;
}
q = p;
}
*pp = p + 1;
} /* _new */
*ptr = p;
}
void _dis(int n, void** ptr)
{
free(*ptr);
*ptr = NULL;
}

View file

@ -1,49 +0,0 @@
#
; $Id$
; (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
;
; This product is part of the Amsterdam Compiler Kit.
;
; Permission to use, sell, duplicate or disclose this software must be
; obtained in writing. Requests for such permissions may be sent to
;
; Dr. Andrew S. Tanenbaum
; Wiskundig Seminarium
; Vrije Universiteit
; Postbox 7161
; 1007 MC Amsterdam
; The Netherlands
;
/* Author: J.W. Stevenson */
mes 2,EM_WSIZE,EM_PSIZE
#define PTRAD 0
#define HP 2
; _sav called with one parameter:
; - address of pointer variable (PTRAD)
exp $_sav
pro $_sav,0
lor HP
lal PTRAD
loi EM_PSIZE
sti EM_PSIZE
ret 0
end ?
; _rst is called with one parameter:
; - address of pointer variable (PTRAD)
exp $_rst
pro $_rst,0
lal PTRAD
loi EM_PSIZE
loi EM_PSIZE
str HP
ret 0
end ?

View file

@ -38,6 +38,7 @@ ea_1_16(param)
}
}
void
ea_1(param) {
if (! address_long) {
ea_1_16(param);
@ -134,6 +135,7 @@ regsize(sz)
}
}
void
indexed() {
if (address_long) {
mod_2 = 0;

View file

@ -61,6 +61,7 @@ string holstr(n) word n; {
full lbytes;
#endif
void
prolog(nlocals) full nlocals; {
fputs("push ebp\nmov ebp,esp\n", codefile);
@ -179,6 +180,7 @@ mach_option(s)
}
#endif /* MACH_OPTIONS */
void
mes(type) word type ; {
int argt, a1, a2 ;

View file

@ -54,6 +54,7 @@ con_float() {
}
void
prolog(nlocals) full nlocals; {
fprintf(codefile,"\tpush\tb\n\tlxi\th,0\n\tdad\tsp\n\tmov\tb,h\n\tmov\tc,l\n");
@ -67,6 +68,7 @@ prolog(nlocals) full nlocals; {
}
}
void
mes(type) word type ; {
int argt ;

View file

@ -61,6 +61,7 @@ string holstr(n) word n; {
full lbytes;
#endif
void
prolog(nlocals) full nlocals; {
fputs("\tpush\tbp\n\tmov\tbp,sp\n", codefile);
@ -157,6 +158,7 @@ regreturn()
}
#endif /* REGVARS */
void
mes(type) word type ; {
int argt ;

View file

@ -21,6 +21,8 @@
* then emitted in one go, by emit_instr().
*/
void move_special();
emit_instr()
{
register instr_t *ip;
@ -70,6 +72,7 @@ long words;
T_EMIT2((short)(words), 0, 0, 0);
}
void
ea_1(sz, bits)
{
/* Because displacements come in three sizes (null displacement,
@ -242,6 +245,7 @@ badoperand()
serror("bad operand(s)");
}
void
shift_op(opc, sz)
{
if (mrg_1 < 010 && mrg_2 < 010) {
@ -263,6 +267,7 @@ shift_op(opc, sz)
ea_2(SIZE_W, MEM|ALT);
}
void
bitop(opc)
{
register bits;
@ -291,6 +296,7 @@ bitfield(opc, extension)
ea_2(SIZE_L, (mrg_2 < 010) ? 0 : (CTR | ALT));
}
void
add(opc, sz)
{
if ((mrg_2 & 070) == 010)
@ -326,6 +332,7 @@ add(opc, sz)
badoperand();
}
void
and(opc, sz)
{
if (mrg_1 == 074 && mrg_2 >= 076) { /* ccr or sr */
@ -370,6 +377,7 @@ from_dreg(opc, sz, bits)
return(1);
}
void
cmp(sz)
{
register opc;
@ -416,6 +424,7 @@ link_instr(sz, areg)
ea_2(sz, 0);
}
void
move(sz)
{
register opc;
@ -448,6 +457,7 @@ move(sz)
ea_2(sz, ALT);
}
void
move_special(sz)
{
if (mrg_2 >= 076) {
@ -514,6 +524,7 @@ reverse(regs, max)
return regs;
}
void
movep(sz)
{
checksize(sz, 2|4);
@ -530,6 +541,7 @@ movep(sz)
badoperand();
}
void
branch(opc, exp)
expr_t exp;
{
@ -566,6 +578,7 @@ expr_t exp;
T_EMIT4(exp.val, exp.typ, RELPC|RELO4, relonami);
}
void
cpbcc(opc, exp)
expr_t exp;
{
@ -593,6 +606,7 @@ expr_t exp;
T_EMIT4(exp.val, exp.typ, RELPC|RELO4, relonami);
}
void
ea7071(sz)
{
mrg_2 = 071;
@ -671,6 +685,7 @@ ea7071(sz)
mrg_2 = 070;
}
void
fbranch(opc, exp)
expr_t exp;
{

View file

@ -187,6 +187,7 @@ regsave(s,off,size)
fprintf(codefile, "!Local %ld into %s\n",off,s);
}
void
prolog(n) full n; {
nlocals = n;
@ -207,6 +208,7 @@ mach_option(s)
}
#endif /* MACH_OPTIONS */
void
mes(type) word type ; {
int argt, a1, a2 ;

View file

@ -19,6 +19,8 @@
#undef word_t
#define word_t long
typedef uint32_t quad;
#undef ALIGNWORD
#define ALIGNWORD 4

View file

@ -49,6 +49,7 @@
%token <y_word> OP_RS_RA_NB
%token <y_word> OP_RS_RA_RB
%token <y_word> OP_RS_RA_RB_C
%token <y_word> OP_RS_RA_RA_C
%token <y_word> OP_RS_RA_RB_MB5_ME5_C
%token <y_word> OP_RS_RA_RB_MB6_C
%token <y_word> OP_RS_RA_RB_ME6_C
@ -80,6 +81,7 @@
%token <y_word> OP_TO_RA_RB
%token <y_word> OP_TO_RA_SI
%token <y_word> OP_LA
%token <y_word> OP_LI32
/* Other token types */

View file

@ -99,6 +99,9 @@
/* Special instructions */
0, OP_LI32, 0, "li32",
0, OP_LA, 0, "la",
0, OP_LA, 0, "li",
0, OP_RS_RA_RA_C, 31<<26 | 444<<1, "mr",
/* Branch processor instructions (page 20) */

View file

@ -44,6 +44,7 @@ operation
| OP_RS_RA_UI_CC C GPR ',' GPR ',' e16 { emit4($1 | ($5<<21) | ($3<<16) | $7); }
| OP_RS_RA_RB GPR ',' GPR ',' GPR { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
| OP_RS_RA_RB_C c GPR ',' GPR ',' GPR { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11)); }
| OP_RS_RA_RA_C c GPR ',' GPR { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($5<<11)); }
| OP_RS_RA_RB_MB5_ME5_C c GPR ',' GPR ',' GPR ',' u5 ',' u5 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | ($9<<6) | ($11<<1)); }
| OP_RS_RA_RB_MB6_C c GPR ',' GPR ',' GPR ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | (($9&0x1F)<<6) | (($9&0x20)>>0)); }
| OP_RS_RA_RB_ME6_C c GPR ',' GPR ',' GPR ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | (($9&0x1F)<<6) | (($9&0x20)>>0)); }
@ -195,10 +196,17 @@ bda
li32
: GPR ',' expr
{
quad type = $3.typ & S_TYP;
quad val = $3.val;
if ((type == S_ABS) && (val <= 0xffff))
emit4((14<<26) | ($1<<21) | (0<<16) | val); /* addi */
else
{
newrelo($3.typ, RELOPPC | FIXUPFLAGS);
emit4((15<<26) | ($1<<21) | (0<<16) | ($3.val >> 16)); /* addis */
emit4((24<<26) | ($1<<21) | ($1<<16) | ($3.val & 0xffff)); /* ori */
emit4((15<<26) | ($1<<21) | (0<<16) | (val >> 16)); /* addis */
emit4((24<<26) | ($1<<21) | ($1<<16) | (val & 0xffff)); /* ori */
}
}
;

View file

@ -1,12 +1,19 @@
for _, plat in ipairs(vars.plats) do
acklibrary {
name = "headers_"..plat,
hdrs = { "./*.h" }
}
acklibrary {
name = "lib_"..plat,
srcs = {
"./*.s",
"./*.e",
},
vars = { plat = plat },
deps = {
"h+emheaders"
"h+emheaders",
"+headers_"..plat,
}
}
end

View file

@ -12,11 +12,14 @@
! address and jumps to it.
! traps if resulting address is zero
!
! On entry: r3 = address of CSA table
! r4 = value
! Stack: ( value tableaddr -- )
.define .csa
.csa:
lwz r3, 0(sp)
lwz r4, 4(sp)
addi sp, sp, 8
lwz r5, 0(r3) ! load default
mtspr ctr, r5

View file

@ -12,11 +12,14 @@
! address and jumps to it.
! traps if resulting address is zero
!
! On entry: r3 = address of CSB table
! r4 = value
! Stack: ( value tableaddr -- )
.define .csb
.csb:
lwz r3, 0(sp)
lwz r4, 4(sp)
addi sp, sp, 8
lwz r5, 0(r3) ! load default
mtspr ctr, r5

26
mach/powerpc/libem/inn.s Normal file
View file

@ -0,0 +1,26 @@
#include "powerpc.h"
.sect .text
/* Tests a bit in a bitset on the stack.
*
* Stack: ( bitset bitnum setsize -- bool )
*/
.define .inn
.inn:
lwz r3, 0(sp) /* r3 = size (bytes) */
lwz r4, 4(sp) /* r4 = bit number */
addi r5, sp, 8 /* r5 = base address of bit set */
srawi r6, r4, 3 /* r6 = byte address into set */
andi. r7, r4, 7 /* r7 = bit within byte */
lbzx r8, r5, r6 /* r8 = individual byte from set */
sraw r8, r8, r7
rlwinm r8, r8, 0, 31, 31
addi sp, sp, 8 /* retract over the two words */
add sp, sp, r3 /* retract over bitfield */
stwu r8, -4(sp) /* push result */
bclr ALWAYS, 0, 0 /* return */

333
mach/powerpc/mcg/platform.c Normal file
View file

@ -0,0 +1,333 @@
#include "mcg.h"
/* mcg stack frames are laid out as:
*
* | ...params...
* | --------------- <- ab
* | old FR
* | old FP
* | --------------- <- fp (a.k.a. lb)
* | locals
* | ---------------
* | spills
* | --------------- <- sb
* | saved regs
* | --------------- <- sp, rb
* V ...user area...
*
* st indexes up; lb indexes down.
*
* Note that [fp] == old_fp and ab == fp + 8.
*/
static ARRAYOF(struct hreg) saved_regs;
void platform_calculate_offsets(void)
{
int i;
saved_regs.count = 0;
for (i=0; i<current_proc->usedregs.count; i++)
{
struct hreg* hreg = current_proc->usedregs.item[i];
if (!(hreg->attrs & burm_volatile_ATTR) &&
((hreg->attrs & burm_long_ATTR) || (hreg->attrs & burm_double_ATTR)))
{
hreg->offset = current_proc->saved_size;
current_proc->saved_size += 8;
array_append(&saved_regs, hreg);
}
}
for (i=0; i<current_proc->usedregs.count; i++)
{
struct hreg* hreg = current_proc->usedregs.item[i];
if (!(hreg->attrs & burm_volatile_ATTR) &&
((hreg->attrs & burm_int_ATTR) || (hreg->attrs & burm_float_ATTR)))
{
hreg->offset = current_proc->saved_size;
current_proc->saved_size += 4;
array_append(&saved_regs, hreg);
}
}
current_proc->fp_to_ab = 8;
current_proc->fp_to_lb = 0;
current_proc->fp_to_sb = -(current_proc->locals_size + current_proc->spills_size);
current_proc->fp_to_rb = current_proc->fp_to_sb - current_proc->saved_size;
}
struct hop* platform_prologue(void)
{
int i;
int spoffset = current_proc->saved_size + current_proc->spills_size +
current_proc->locals_size;
struct hop* hop = new_hop(current_proc->entry, NULL);
hop_add_insel(hop, "! locals_size = %d", current_proc->locals_size);
hop_add_insel(hop, "! spills_size = %d", current_proc->spills_size);
hop_add_insel(hop, "! saved_size = %d", current_proc->saved_size);
hop_add_insel(hop, "! params @ fp+%d", current_proc->fp_to_ab);
hop_add_insel(hop, "! lr @ fp+4");
hop_add_insel(hop, "! fp @ fp+0");
hop_add_insel(hop, "! locals @ fp-%d to fp+0",
current_proc->locals_size);
hop_add_insel(hop, "! spills @ fp-%d to fp-%d",
-current_proc->fp_to_sb, current_proc->locals_size);
for (i=saved_regs.count-1; i>=0; i--)
{
struct hreg* hreg = saved_regs.item[i];
hop_add_insel(hop, "! %s @ fp-%d",
hreg->id, -(current_proc->fp_to_rb + hreg->offset));
}
hop_add_insel(hop, "addi sp, sp, %d", -(spoffset + 8));
hop_add_insel(hop, "mfspr r0, lr");
hop_add_insel(hop, "stw fp, %d(sp)", spoffset + 0);
hop_add_insel(hop, "stw r0, %d(sp)", spoffset + 4);
hop_add_insel(hop, "addi fp, sp, %d", spoffset);
/* Saved reg offsets are negative. */
for (i=0; i<saved_regs.count; i++)
{
struct hreg* hreg = saved_regs.item[i];
if (hreg->attrs & burm_int_ATTR)
hop_add_insel(hop, "stw %H, %d(fp)",
hreg, current_proc->fp_to_rb + hreg->offset);
else if (hreg->attrs & burm_float_ATTR)
hop_add_insel(hop, "stfs %H, %d(fp)",
hreg, current_proc->fp_to_rb + hreg->offset);
}
return hop;
}
struct hop* platform_epilogue(void)
{
struct hop* hop = new_hop(current_proc->exit, NULL);
int i;
for (i=0; i<saved_regs.count; i++)
{
struct hreg* hreg = saved_regs.item[i];
if (hreg->attrs & burm_int_ATTR)
hop_add_insel(hop, "lwz %H, %d(fp)",
hreg, current_proc->fp_to_rb + hreg->offset);
else if (hreg->attrs & burm_float_ATTR)
hop_add_insel(hop, "lfs %H, %d(fp)",
hreg, current_proc->fp_to_rb + hreg->offset);
}
hop_add_insel(hop, "lwz r0, 4(fp)");
hop_add_insel(hop, "mtspr lr, r0");
hop_add_insel(hop, "lwz r0, 0(fp)"); /* load old fp */
hop_add_insel(hop, "addi sp, fp, %d", current_proc->fp_to_ab);
hop_add_insel(hop, "mr fp, r0");
hop_add_insel(hop, "bclr 20, 0, 0");
return hop;
}
struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg* dest)
{
struct hop* hop = new_hop(bb, NULL);
if ((src->attrs & TYPE_ATTRS) != (dest->attrs & TYPE_ATTRS))
{
assert(!src->is_stacked);
assert(!dest->is_stacked);
switch (src->attrs & TYPE_ATTRS)
{
case burm_int_ATTR:
hop_add_insel(hop, "stwu %H, -4(sp)", src);
break;
case burm_long_ATTR:
hop_add_insel(hop, "stwu %0H, -4(sp)", src);
hop_add_insel(hop, "stwu %1H, -4(sp)", src);
break;
case burm_float_ATTR:
hop_add_insel(hop, "stfsu %H, -4(sp)", src);
break;
case burm_double_ATTR:
hop_add_insel(hop, "stfdu %H, -8(sp)", src);
break;
default:
goto nomove;
}
switch (dest->attrs & TYPE_ATTRS)
{
case burm_int_ATTR:
hop_add_insel(hop, "lwz %H, 0(sp)", dest);
break;
case burm_long_ATTR:
hop_add_insel(hop, "lwz %0H, 4(sp)", dest);
hop_add_insel(hop, "lwz %1H, 0(sp)", dest);
break;
case burm_float_ATTR:
hop_add_insel(hop, "lfs %H, 0(sp)", dest);
break;
case burm_double_ATTR:
hop_add_insel(hop, "lfd %H, 0(sp)", dest);
break;
default:
goto nomove;
}
switch (dest->attrs & TYPE_ATTRS)
{
case burm_int_ATTR:
case burm_float_ATTR:
hop_add_insel(hop, "addi sp, sp, 4");
break;
case burm_double_ATTR:
case burm_long_ATTR:
hop_add_insel(hop, "addi sp, sp, 8");
break;
default:
goto nomove;
}
}
else
{
uint32_t type = src->attrs & TYPE_ATTRS;
if (!src->is_stacked && dest->is_stacked)
{
switch (type)
{
case burm_int_ATTR:
hop_add_insel(hop, "stw %H, %S(fp) ! %H", src, dest, dest);
break;
case burm_float_ATTR:
hop_add_insel(hop, "stfs %H, %S(fp) ! %H", src, dest, dest);
break;
case burm_long_ATTR:
hop_add_insel(hop, "stw %0H, 4+%S(fp) ! %H", src, dest, dest);
hop_add_insel(hop, "stw %1H, 0+%S(fp) ! %H", src, dest, dest);
break;
case burm_double_ATTR:
hop_add_insel(hop, "stfd %H, %S(fp) ! %H", src, dest, dest);
break;
default:
goto nomove;
}
}
else if (src->is_stacked && !dest->is_stacked)
{
switch (type)
{
case burm_int_ATTR:
hop_add_insel(hop, "lwz %H, %S(fp) ! %H", dest, src, src);
break;
case burm_float_ATTR:
hop_add_insel(hop, "lfs %H, %S(fp) ! %H", dest, src, src);
break;
case burm_double_ATTR:
hop_add_insel(hop, "lfd %H, %S(fp) ! %H", dest, src, src);
break;
default:
goto nomove;
}
}
else if (!src->is_stacked && !dest->is_stacked)
{
switch (type)
{
case burm_int_ATTR:
hop_add_insel(hop, "mr %H, %H", dest, src);
break;
case burm_long_ATTR:
hop_add_insel(hop, "mr %0H, %0H", dest, src);
hop_add_insel(hop, "mr %1H, %1H", dest, src);
break;
case burm_float_ATTR:
case burm_double_ATTR:
hop_add_insel(hop, "fmr %H, %H", dest, src);
break;
default:
goto nomove;
}
}
else
goto nomove;
}
return hop;
nomove:
fatal("cannot move %s to %s", src->id, dest->id);
}
struct hop* platform_swap(struct basicblock* bb, struct hreg* src, struct hreg* dest)
{
struct hop* hop = new_hop(bb, NULL);
assert(!src->is_stacked);
assert(!dest->is_stacked);
assert((src->attrs & TYPE_ATTRS) == (dest->attrs & TYPE_ATTRS));
switch (src->attrs & TYPE_ATTRS)
{
case burm_int_ATTR:
hop_add_insel(hop, "mr r0, %H", src);
hop_add_insel(hop, "mr %H, %H", src, dest);
hop_add_insel(hop, "mr %H, r0", dest);
break;
case burm_long_ATTR:
hop_add_insel(hop, "mr r0, %0H", src);
hop_add_insel(hop, "mr %0H, %0H", src, dest);
hop_add_insel(hop, "mr %0H, r0", dest);
hop_add_insel(hop, "mr r0, %1H", src);
hop_add_insel(hop, "mr %1H, %1H", src, dest);
hop_add_insel(hop, "mr %1H, r0", dest);
break;
case burm_float_ATTR:
case burm_double_ATTR:
hop_add_insel(hop, "fmr f0, %H", src);
hop_add_insel(hop, "fmr %H, %H", src, dest);
hop_add_insel(hop, "fmr %H, f0", dest);
break;
}
return hop;
}
const char* platform_label(const char* label)
{
/* Labels starting with . are internal, not exported, and don't need mangling. */
if (label[0] == '.')
return label;
/* Otherwise, mangle. */
return aprintf("_%s", label);
}
/* vim: set sw=4 ts=4 expandtab : */

794
mach/powerpc/mcg/table Normal file
View file

@ -0,0 +1,794 @@
REGISTERS
/* Registers are allocated top down; the order here is odd in order to make
* sure that non-volatile registers get allocated from r31 (or f31) down.
*
* Attributes may have at most one of: int, float, long, double. These
* indicate that the register is used to store a value of that type. If
* your register can store more than one type, create an alias. Registers
* with none of these cannot be copied by the code generator (and so cannot
* be moved from register to register or spilt).
*/
r12 int volatile;
r11 int volatile;
r10 int volatile;
r9 int volatile;
r8 int volatile;
r7 int volatile;
r6 int volatile;
r5 int volatile;
r4 int volatile;
r3 int volatile iret;
r31 int;
r30 int;
r29 int;
r28 int;
r27 int;
r26 int;
r25 int;
r24 int;
r23 int;
r22 int;
r21 int;
r20 int;
r19 int;
r18 int;
r17 int;
r16 int;
r15 int;
r14 int;
r13 int;
r11r12 named("r11", "r12") aliases(r11, r12) long volatile;
r9r10 named("r9", "r10") aliases(r9, r10) long volatile;
r7r8 named("r7", "r8") aliases(r7, r8) long volatile;
r5r6 named("r5", "r6") aliases(r6, r6) long volatile;
r3r4 named("r3", "r4") aliases(r3, r4) long volatile lret;
r29r30 named("r29", "r30") aliases(r29, r30) long;
r27r28 named("r27", "r28") aliases(r27, r28) long;
r25r26 named("r25", "r26") aliases(r25, r26) long;
r23r24 named("r23", "r24") aliases(r23, r24) long;
r21r22 named("r21", "r22") aliases(r21, r22) long;
r19r20 named("r19", "r20") aliases(r19, r20) long;
r17r18 named("r17", "r18") aliases(r17, r18) long;
r15r16 named("r15", "r16") aliases(r15, r16) long;
r13r14 named("r13", "r14") aliases(r13, r14) long;
f14 float volatile;
f13 float volatile;
f12 float volatile;
f11 float volatile;
f10 float volatile;
f9 float volatile;
f8 float volatile;
f7 float volatile;
f6 float volatile;
f5 float volatile;
f4 float volatile;
f3 float volatile fret;
f2 float volatile;
f1 float volatile;
f0 float volatile;
f31 float;
f30 float;
f29 float;
f28 float;
f27 float;
f26 float;
f25 float;
f24 float;
f23 float;
f22 float;
f21 float;
f20 float;
f19 float;
f18 float;
f17 float;
f16 float;
f15 float;
d14 named("f14") aliases(f14) double volatile;
d13 named("f13") aliases(f13) double volatile;
d12 named("f12") aliases(f12) double volatile;
d11 named("f11") aliases(f11) double volatile;
d10 named("f10") aliases(f10) double volatile;
d9 named("f9") aliases(f9) double volatile;
d8 named("f8") aliases(f8) double volatile;
d7 named("f7") aliases(f7) double volatile;
d6 named("f6") aliases(f6) double volatile;
d5 named("f5") aliases(f5) double volatile;
d4 named("f4") aliases(f4) double volatile;
d3 named("f3") aliases(f3) double volatile dret;
d2 named("f2") aliases(f2) double volatile;
d1 named("f1") aliases(f1) double volatile;
d0 named("f0") aliases(f0) double volatile;
d31 named("f31") aliases(f31) double;
d30 named("f30") aliases(f30) double;
d29 named("f29") aliases(f29) double;
d28 named("f28") aliases(f28) double;
d27 named("f27") aliases(f27) double;
d26 named("f26") aliases(f26) double;
d25 named("f25") aliases(f25) double;
d24 named("f24") aliases(f24) double;
d23 named("f23") aliases(f23) double;
d22 named("f22") aliases(f22) double;
d21 named("f21") aliases(f21) double;
d20 named("f20") aliases(f20) double;
d19 named("f19") aliases(f19) double;
d18 named("f18") aliases(f18) double;
d17 named("f17") aliases(f17) double;
d16 named("f16") aliases(f16) double;
d15 named("f15") aliases(f15) double;
cr0 cr;
DECLARATIONS
cr;
ubyteX; /* bottom 8 bits valid, the rest undefined */
ubyte0; /* bottom 8 bits valid, the rest 0 */
ushortX; /* bottom 16 bits valid, the rest undefined */
ushort0; /* bottom 16 bits valid, the rest 0 */
address fragment;
PATTERNS
/* Special */
PAIR(BLOCK.I, BLOCK.I);
/* Miscellaneous special things */
PUSH.I(in:(int)reg)
emit "stwu %in, -4(sp)"
cost 4;
PUSH.L(in:(long)reg)
emit "stwu %in.0, -4(sp)"
emit "stwu %in.1, -4(sp)"
cost 8;
PUSH.D(in:(double)reg)
emit "stfdu %in, -8(sp)"
cost 4;
out:(int)reg = POP.I
emit "lwz %out, 0(sp)"
emit "addi sp, sp, 4"
cost 8;
out:(long)reg = POP.L
emit "lwz %out.0, 4(sp)"
emit "lwz %out.1, 0(sp)"
emit "addi sp, sp, 8"
cost 12;
out:(float)reg = POP.F
emit "lfs %out, 0(sp)"
emit "addi sp, sp, 4"
cost 8;
out:(double)reg = POP.D
emit "lfd %out, 0(sp)"
emit "addi sp, sp, 8"
cost 8;
SETRET.I(in:(iret)reg)
emit "! setret4"
cost 1;
SETRET.L(in:(lret)reg)
emit "! setret8"
cost 1;
STACKADJUST.I(delta:CONST.I)
when signed_constant(%delta, 16)
emit "addi sp, sp, $delta"
cost 4;
STACKADJUST.I(in:(int)reg)
emit "add sp, sp, %in"
cost 4;
STACKADJUST.I(NEG.I(in:(int)reg))
emit "subf sp, %in, sp"
cost 4;
out:(int)reg = GETFP.I
emit "mr %out, fp"
cost 4;
SETFP.I(in:(int)reg)
emit "mr fp, %in"
cost 4;
out:(int)reg = CHAINFP.I(in:(int)reg)
emit "lwz %out, 0(%in)"
cost 4;
out:(int)reg = FPTOAB.I(GETFP.I)
emit "addi %out, fp, 8"
cost 4;
out:(int)reg = FPTOAB.I(in:(int)reg)
emit "addi %out, %in, 8"
cost 4;
out:(int)reg = FPTOLB.I(in:(int)reg)
with %out == %in
cost 1;
out:(int)reg = GETSP.I
emit "mr %out, sp"
cost 4;
SETSP.I(in:(int)reg)
emit "mr sp, %in"
cost 4;
out:(int)reg = ANY.I
cost 1;
out:(int)reg = COPYF.I(in:(float)reg)
emit "stfsu %in, -4(sp)"
emit "lwz %out, 0(sp)"
emit "addi sp, sp, 4"
cost 12;
out:(double)reg = COPYL.D(in:(long)reg)
emit "stwu %in.0, -4(sp)"
emit "stwu %in.1, -4(sp)"
emit "lfd %out, 0(sp)"
emit "addi sp, sp, 8"
cost 16;
out:(long)reg = COPYD.L(in:(double)reg)
emit "stfdu %in, -8(sp)"
emit "lwz %out.0, 4(sp)"
emit "lwz %out.1, 0(sp)"
emit "addi sp, sp, 8"
cost 16;
/* Memory operations */
/* Stores */
STORE.D(addr:address, value:(double)reg)
emit "stfd %value, %addr"
cost 4;
STORE.L(addr:address, value:(long)reg)
emit "stw %value.0, 4+%addr"
emit "stw %value.1, 0+%addr"
cost 8;
STORE.I(addr:address, value:(int)reg)
emit "stw %value, %addr"
cost 4;
STOREH.I(addr:address, value:(int)ushortX)
emit "sth %value, %addr"
cost 4;
STOREH.I(ADD.I(left:(int)reg, right:(int)reg), value:(int)ushortX)
emit "sthx %value, %left, %right"
cost 4;
STOREB.I(addr:address, value:(int)ushortX)
emit "sth %value, %addr"
cost 4;
STOREB.I(addr:address, value:(int)ubyteX)
emit "stb %value, %addr"
cost 4;
STOREB.I(ADD.I(left:(int)reg, right:(int)reg), value:(int)ubyteX)
emit "stbx %value, %left, %right"
cost 4;
/* Loads */
out:(int)reg = LOAD.I(addr:address)
emit "lwz %out, %addr"
cost 4;
out:(long)reg = LOAD.L(addr:address)
emit "lwz %out.0, 4+%addr"
emit "lwz %out.1, 0+%addr"
cost 8;
out:(int)ushort0 = LOADH.I(addr:address)
emit "lhz %out, %addr"
cost 4;
out:(int)ubyte0 = LOADB.I(addr:address)
emit "lbz %out, %addr"
cost 4;
/* ubyte intrinsics */
out:(int)ubyteX = in:(int)ubyte0
with %out == %in
emit "! ubyte0 -> ubyteX"
cost 1;
out:(int)ubyte0 = in:(int)ubyteX
emit "andi %out, %in, 0xff ! ubyteX -> ubyte0"
cost 4;
out:(int)reg = in:(int)ubyte0
with %out == %in
emit "! ubyte0 -> reg"
cost 4;
out:(int)ubyteX = in:(int)reg
with %out == %in
emit "! reg -> ubyteX"
cost 1;
/* ushort intrinsics */
out:(int)ushortX = in:(int)ushort0
with %out == %in
emit "! ushort0 -> ushortX"
cost 1;
out:(int)ushort0 = in:(int)ushortX
emit "andi %out, %in, 0xff ! ushortX -> ushort0"
cost 4;
out:(int)reg = in:(int)ushort0
with %out == %in
emit "! ushort0 -> reg"
cost 4;
out:(int)ushortX = in:(int)reg
with %out == %in
emit "! reg -> ushortX"
cost 1;
/* Extensions and conversions */
out:(int)reg = EXTENDB.I(in:(int)reg)
emit "extsb %out, %in"
cost 4;
out:(int)reg = EXTENDH.I(in:(int)reg)
emit "extsh %out, %in"
cost 4;
out:(int)reg = FROMSI.I(in:(int)reg)
with %out == %in
emit "! FROMSI.I(int) -> int"
cost 1;
out:(int)reg = FROMUI.I(in:(int)reg)
with %out == %in
emit "! FROMUI.I(int) -> int"
cost 1;
out:(long)reg = FROMSI.L(in:(int)reg)
emit "mr %out.0, %in"
emit "srawi %out.1, %out.0, 31"
cost 8;
out:(long)reg = FROMUI.L(in:(int)reg)
emit "mr %out.0, %in"
emit "li32 %out.1, 0"
cost 8;
out:(iret)reg = FROMSF.I(in:(dret)reg)
with corrupted(volatile)
emit "bl .fromf2i"
cost 4;
out:(int)reg = FROMSD.I(in:(double)reg)
with preserved(%in)
emit "fctiwz %in, %in"
emit "stfdu %in, -8(sp)"
emit "lwz %out, 4(sp)"
emit "addi sp, sp, 8"
cost 16;
out:(int)reg = FROMUD.I(in:(double)reg)
with corrupted(volatile)
emit "stfdu %in, -8(sp)"
emit "bl .cfu8"
emit "lwz %out, 0(sp)"
emit "addi sp, sp, 4"
cost 16;
out:(lret)reg = FROMSF.L(in:(fret)reg)
with corrupted(volatile)
emit "bl .fromf2l"
cost 4;
out:(lret)reg = FROMUF.I(in:(fret)reg)
with corrupted(volatile)
emit "bl .fromf2l"
cost 4;
out:(double)reg = FROMSI.D(in:(int)reg)
with corrupted(volatile)
emit "stwu %in, -4(sp)"
emit "bl .cif8"
emit "lfd %out, 0(sp)"
emit "addi sp, sp, 8"
cost 4;
out:(fret)reg = FROMUI.F(in:(iret)reg)
with corrupted(volatile)
emit "bl .fromui2f"
cost 4;
out:(double)reg = FROMUI.D(in:(int)reg)
with corrupted(volatile)
emit "stwu %in, -4(sp)"
emit "bl .cuf8"
emit "lfd %out, 0(sp)"
emit "addi sp, sp, 8"
cost 4;
out:(lret)reg = FROMIPAIR.L(in1:(int)reg, in2:(int)reg)
emit "mr %out.0, %in1"
emit "mr %out.1, %in2"
cost 8;
out:(int)reg = FROML0.I(in:(long)reg)
emit "mr %out, %in.0"
cost 4;
out:(int)reg = FROML1.I(in:(long)reg)
emit "mr %out, %in.1"
cost 4;
/* Locals */
out:(int)reg = in:LOCAL.I
emit "addi %out, fp, $in"
cost 4;
address = in:LOCAL.I
emit "$in(fp)";
/* Memory addressing modes */
address = ADD.I(addr:(int)reg, offset:CONST.I)
when signed_constant(%offset, 16)
emit "$offset(%addr)";
address = addr:(int)reg
emit "0(%addr)";
/* Branches */
JUMP(addr:BLOCK.I)
emit "b $addr"
cost 4;
FARJUMP(addr:LABEL.I)
with corrupted(volatile)
emit "b $addr"
cost 4;
JUMP(dest:(int)reg)
emit "mtspr ctr, %dest"
emit "bcctrl 20, 0, 0"
cost 8;
CJUMPEQ(value:(cr)cr, PAIR(true:BLOCK.I, false:BLOCK.I))
emit "bc 12, 2, $true" /* IFTRUE EQ */
emit "b $false"
cost 8;
CJUMPLE(value:(cr)cr, PAIR(true:BLOCK.I, false:BLOCK.I))
emit "bc 4, 1, $true" /* IFFALSE GT */
emit "b $false"
cost 8;
CJUMPLT(value:(cr)cr, PAIR(true:BLOCK.I, false:BLOCK.I))
emit "bc 12, 0, $true" /* IFTRUE LT */
emit "b $false"
cost 8;
#define CALLLABEL(insn) \
insn (dest:LABEL.I) \
with corrupted(volatile) \
emit "bl $dest" \
cost 4;
CALLLABEL(CALL)
out:(iret)reg = CALLLABEL(CALL.I)
out:(lret)reg = CALLLABEL(CALL.L)
#define CALLINDIRECT(insn) \
insn (dest:(int)reg) \
with corrupted(volatile) \
emit "mtspr ctr, %dest" \
emit "bcctrl 20, 0, 0" \
cost 8;
CALLINDIRECT(CALL)
out:(iret)reg = CALLINDIRECT(CALL.I)
out:(lret)reg = CALLINDIRECT(CALL.L)
JUMP(dest:LABEL.I)
emit "b $dest"
cost 4;
/* Comparisons */
cr:(cr)cr = COMPARESI.I(left:(int)reg, right:(int)reg)
emit "cmp %cr, 0, %left, %right"
cost 4;
cr:(cr)cr = COMPARESI.I(left:(int)reg, right:CONST.I)
when signed_constant(%right, 16)
emit "cmpi %cr, 0, %left, $right"
cost 4;
cr:(cr)cr = COMPAREUI.I(left:(int)reg, right:(int)reg)
emit "cmpl %cr, 0, %left, %right"
cost 4;
cr:(cr)cr = COMPAREUI.I(left:(int)reg, right:CONST.I)
when signed_constant(%right, 16)
emit "cmpli %cr, 0, %left, $right"
cost 4;
out:(cr)cr = COMPARESI.I(in:(cr)cr, result:CONST.I)
when specific_constant(%result, 0)
with %out == %in
emit "! COMPARESI.I(cr, 0)"
cost 4;
/* Booleans */
out:(int)reg = IFEQ.I(in:(cr)cr)
emit "mfcr %out" /* get cr0 */
emit "rlwinm %out, %out, [32-2], 2, 31" /* extract just EQ */
cost 8;
out:(int)reg = IFEQ.I(in:(int)reg)
emit "cntlzw %out, %in" /* returns 0..32 */
emit "rlwinm %out, %out, [32-5], 5, 31" /* if 32, return 1, otherwise 0 */
cost 8;
out:(int)reg = IFLT.I(in:(cr)cr)
emit "mfcr %out" /* get cr0 */
emit "andi. %out, %out, 1" /* leave just LT */
cost 8;
out:(int)reg = IFLE.I(in:(cr)cr)
emit "mfcr %out" /* get cr0 */
emit "andi. %out, %out, 5" /* leave just LT and EQ */
emit "cntlzw %out, %out" /* returns 0..32 */
emit "rlwinm %out, %out, [32-5], 5, 31" /* if 32, return 1, otherwise 0 */
emit "xori %out, %out, 1" /* negate */
cost 8;
/* Conversions */
#if 0
out:(int)reg = CIU44(in:(int)reg)
with %out == %in
emit "! ciu44"
cost 4;
out:(int)reg = CUI44(in:(int)reg)
with %out == %in
emit "! cui44"
cost 4;
#endif
/* ALU operations */
#define ALUR(name, instr) \
out:(int)reg = name(left:(int)reg, right:(int)reg) \
emit instr " %out, %left, %right" \
cost 4; \
#define ALUC(name, instr) \
out:(int)reg = name(left:(int)reg, right:CONST.I) \
when signed_constant(%right, 16) \
emit instr " %out, %left, $right" \
cost 4; \
#define ALUC_reversed(name, instr) \
out:(int)reg = name(left:CONST.I, right:(int)reg) \
when signed_constant(%left, 16) \
emit instr " %out, %right, $left" \
cost 4; \
#define ALUCC(name, instr) \
ALUC(name, instr) \
ALUC_reversed(name, instr)
ALUR(ADD.I, "add")
ALUCC(ADD.I, "addi")
out:(int)reg = SUB.I(left:(int)reg, right:(int)reg)
emit "subf %out, %right, %left"
cost 4;
out:(int)reg = SUB.I(left:(int)reg, right:CONST.I)
emit "addi %out, %left, -[$right]"
cost 4;
out:(int)reg = MOD.I(left:(int)reg, right:(int)reg)
with preserved(%left), preserved(%right)
emit "divw %out, %left, %right"
emit "mullw %out, %out, %right"
emit "subf %out, %out, %left"
cost 12;
out:(int)reg = MODU.I(left:(int)reg, right:(int)reg)
with preserved(%left), preserved(%right)
emit "divwu %out, %left, %right"
emit "mullw %out, %out, %right"
emit "subf %out, %out, %left"
cost 12;
ALUR(MUL.I, "mullw")
ALUCC(MUL.I, "mulli")
ALUR(DIV.I, "divw")
ALUR(DIVU.I, "divwu")
ALUR(ASL.I, "slw")
ALUR(ASR.I, "sraw")
ALUR(LSL.I, "slw")
ALUR(LSR.I, "srw")
out:(int)reg = NEG.I(left:(int)reg)
emit "neg %out, %left"
cost 4;
out:(int)reg = NOT.I(left:(int)reg)
emit "cntlzw %out, %left"
emit "rlwinm %out, %out, 32-5, 5, 31"
cost 8;
ALUR(AND.I, "and")
ALUCC(AND.I, "andi.")
ALUR(OR.I, "or")
ALUCC(OR.I, "ori")
ALUR(EOR.I, "xor")
ALUCC(EOR.I, "xori")
out:(int)reg = value:LABEL.I
emit "li32 %out, $value"
cost 4;
out:(int)reg = value:BLOCK.I
emit "li32 %out, $value"
cost 4;
out:(int)reg = value:CONST.I
emit "li32 %out, $value"
cost 8;
/* FPU operations */
#define FPU4R(name, instr) \
out:(float)reg = name(left:(float)reg, right:(float)reg) \
emit instr " %out, %left, %right" \
cost 4; \
#define FPU8R(name, instr) \
out:(double)reg = name(left:(double)reg, right:(double)reg) \
emit instr " %out, %left, %right" \
cost 4; \
out:(float)reg = LOAD.F(addr:address)
emit "lfs %out, %addr"
cost 4;
out:(double)reg = LOAD.D(addr:address)
emit "lfd %out, %addr"
cost 4;
out:(float)reg = in:CONST.F
when specific_constant(%in, 0)
emit "li32 r0, .fd_00000000"
emit "lfs %out, 0(r0)"
cost 12;
FPU4R(ADDF.F, "fadds")
FPU8R(ADDF.D, "fadd")
FPU4R(SUBF.F, "fsubs")
FPU8R(SUBF.D, "fsub")
FPU4R(MULF.F, "fmuls")
FPU8R(MULF.D, "fmul")
FPU4R(DIVF.F, "fdivs")
FPU8R(DIVF.D, "fdiv")
#define FMALEFT(type, insn, add, mul) \
out:(type)reg = add(mul(m1:(type)reg, m2:(type)reg), m3:(type)reg) \
emit insn " %out, %m1, %m2, %m3" \
cost 4; \
#define FMARIGHT(type, insn, add, mul) \
out:(type)reg = add(m3:(type)reg, mul(m1:(type)reg, m2:(type)reg)) \
emit insn " %out, %m1, %m2, %m3" \
cost 4; \
FMALEFT( double, "fmadd", ADDF.D, MULF.D)
FMARIGHT(double, "fmadd", ADDF.D, MULF.D)
FMALEFT( float, "fmadds", ADDF.F, MULF.F)
FMARIGHT(float, "fmadds", ADDF.F, MULF.F)
FMALEFT( double, "fmsub", SUBF.D, MULF.D)
FMALEFT( float, "fmsubs", SUBF.F, MULF.F)
FMARIGHT(double, "fnmadd", SUBF.D, MULF.D)
FMARIGHT(float, "fnmadds", SUBF.F, MULF.F)
#define FMANEGLEFT(type, insn, neg, add, mul) \
out:(type)reg = neg(add(mul(m1:(type)reg, m2:(type)reg), m3:(type)reg)) \
emit insn " %out, %m1, %m2, %m3" \
cost 4; \
#define FMANEGRIGHT(type, insn, neg, add, mul) \
out:(type)reg = neg(add(m3:(type)reg, mul(m1:(type)reg, m2:(type)reg))) \
emit insn " %out, %m1, %m2, %m3" \
cost 4; \
FMANEGLEFT( double, "fnmsub", NEGF.D, ADDF.D, MULF.D)
FMANEGRIGHT(double, "fnmsub", NEGF.D, ADDF.D, MULF.D)
FMANEGLEFT( float, "fnmsub", NEGF.F, ADDF.F, MULF.F)
FMANEGRIGHT(float, "fnmsub", NEGF.F, ADDF.F, MULF.F)
out:(float)reg = NEGF.F(left:(float)reg)
emit "fneg %out, %left"
cost 4;
out:(double)reg = NEGF.D(left:(double)reg)
emit "fneg %out, %left"
cost 4;
cr:(cr)cr = COMPAREF.I(left:(float)reg, right:(float)reg)
emit "fcmpu %cr, %left, %right"
cost 4;
cr:(cr)cr = COMPARED.I(left:(double)reg, right:(double)reg)
emit "fcmpu %cr, %left, %right"
cost 4;
/* vim: set sw=4 ts=4 expandtab : */

View file

@ -56,6 +56,7 @@ con_mult(word sz)
#define FL_MSB_AT_LOW_ADDRESS 1
#include <con_float>
void
prolog(full nlocals)
{
int ss = nlocals + 8;
@ -68,6 +69,7 @@ prolog(full nlocals)
framesize = nlocals;
}
void
mes(word type)
{
int argt ;

View file

@ -328,6 +328,7 @@ INSTRUCTIONS
lhax GPR:wo, GPR:ro, GPR:ro cost(4, 3).
lhz GPR:wo, GPRINDIRECT:ro cost(4, 3).
lhzx GPR:wo, GPR:ro, GPR:ro cost(4, 3).
li32 GPR:wo, CONST:ro cost(8, 2).
li32 GPR:wo, LABEL:ro cost(8, 2).
lwzu GPR:wo, GPRINDIRECT:ro cost(4, 3).
lwzx GPR:wo, GPR:ro, GPR:ro cost(4, 3).
@ -1637,14 +1638,13 @@ PATTERNS
gen
bl {LABEL, ".set"}
pat inn defined($1) /* Test for set bit */
leaving
set INT32
and INT32
pat inn !defined($1) /* Test for set bit (variable) */
with GPR3 STACK
pat inn /* Test for set bit */
with STACK
kills ALL
uses REG
gen
li32 %a, {CONST, $1}
stwu %a, {GPRINDIRECT, SP, 0-4}
bl {LABEL, ".inn"}
@ -1898,12 +1898,12 @@ PATTERNS
addi SP, SP, {CONST, 12}
pat csa /* Array-lookup switch */
with GPR3 GPR4 STACK
with STACK
gen
b {LABEL, ".csa"}
pat csb /* Table-lookup switch */
with GPR3 GPR4 STACK
with STACK
gen
b {LABEL, ".csb"}

View file

@ -1,7 +1,8 @@
/* 68020 desciptor table for ACK target optimizer */
/* PowerPC desciptor table for ACK target optimizer */
MAXOP 3;
LABEL_STARTER '.';
%%;
@ -15,6 +16,14 @@ X, Y, Z { TRUE };
addi X, X, 0 -> ;
addis X, X, 0 -> ;
mr X, X -> ;
fmr X, X -> ;
or X, Y, Z : or. X, X, X -> or. X, Y, Z ;
b X : labdef X -> labdef X ;
/* IFFALSE=4, IFTRUE=12, ALWAYS=20 */
/* LT=0, GT=1, EQ=2, OV=3 */
%%;

View file

@ -8,6 +8,8 @@
* All preprocessor based options/constants/functions
*/
#include <stdint.h>
/* ========== ON/OFF options (use #define in mach0.c) ========== */
/*

View file

@ -18,6 +18,9 @@
extern YYSTYPE yylval;
void setupoutput();
void commfinish();
/* ========== Machine independent C routines ========== */
void stop() {
@ -458,6 +461,7 @@ char *s;
#endif
}
void
setupoutput()
{
register sect_t *sp;
@ -493,6 +497,7 @@ setupoutput()
outhead.oh_nchar = off; /* see newsymb() */
}
void
commfinish()
{
#ifndef ASLD

View file

@ -11,6 +11,8 @@
extern YYSTYPE yylval;
void putval();
yylex()
{
register c;
@ -68,6 +70,7 @@ yylex()
return(c);
}
void
putval(c)
{
register valu_t v;

View file

@ -12,6 +12,10 @@
#include "comm1.h"
#include "y.tab.h"
void switchsect();
void newsymb();
void newident();
newequate(ip, typ)
register item_t *ip;
register int typ;
@ -34,6 +38,7 @@ register int typ;
newident(ip, typ);
}
void
newident(ip, typ)
register item_t *ip;
{
@ -74,6 +79,7 @@ register item_t *ip;
);
}
void
newlabel(ip)
register item_t *ip;
{
@ -183,6 +189,7 @@ valu_t val;
}
}
void
switchsect(newtyp)
int newtyp;
{
@ -242,6 +249,7 @@ valu_t bytes;
}
#ifdef RELOCATION
void
newrelo(s, n)
{
int iscomm;
@ -326,6 +334,7 @@ new_string(s)
return r;
}
void
newsymb(name, type, desc, valu)
register char *name;
valu_t valu;

View file

@ -0,0 +1,42 @@
#include "mcg.h"
static void init_idf();
static struct idf* str2idf(char* tg, int cp);
#define IDF_TYPE struct basicblock*
#define IDF_NAME block
#include <idf_pkg.spec>
#include <idf_pkg.body>
static int next_id = 0;
void bb_init(void)
{
init_idf();
}
struct basicblock* bb_get(const char* name)
{
struct idf* p;
if (!name)
name = aprintf(".anon_bb_%d", next_id++);
p = str2idf((char*) name, 0);
if (!p->block)
{
p->block = calloc(1, sizeof(*p->block));
p->block->name = name;
}
return p->block;
}
void bb_alias(struct basicblock* block, const char* name)
{
struct idf* p = str2idf((char*) name, -1);
assert(p == NULL);
p = str2idf((char*) name, 0);
p->block = block;
}
/* vim: set sw=4 ts=4 expandtab : */

View file

@ -0,0 +1,43 @@
#ifndef BASICBLOCK_H
#define BASICBLOCK_H
struct phi
{
struct basicblock* prev; /* Predecessor that this phi is referring to */
struct ir* ir; /* IR of variable definition */
};
struct basicblock
{
const char* name;
ARRAYOF(struct em) ems;
ARRAYOF(struct ir) irs;
ARRAYOF(struct hop) hops;
ARRAYOF(struct basicblock) prevs;
ARRAYOF(struct basicblock) nexts;
int order; /* used by dominance graph code */
PMAPOF(struct vreg, struct phi) phis;
/* Used by liveness calculation. */
ARRAYOF(struct vreg) liveins;
ARRAYOF(struct vreg) liveouts;
/* Register assignments on entry and exit. */
register_assignment_t regsin;
register_assignment_t* regsout; /* points at regsout of the last insn. */
bool is_fake : 1;
bool is_root : 1;
bool is_terminated : 1;
};
extern void bb_init(void);
extern struct basicblock* bb_get(const char* name);
extern void bb_alias(struct basicblock* block, const char* name);
#endif
/* vim: set sw=4 ts=4 expandtab : */

51
mach/proto/mcg/build.lua Normal file
View file

@ -0,0 +1,51 @@
include("util/mcgg/build.lua")
definerule("build_mcg",
{
arch = { type="string" }
},
function(e)
-- Remember this is executed from the caller's directory; local
-- target names will resolve there
local headers = clibrary {
name = e.name.."/headers",
srcs = {},
hdrs = {
"mach/proto/mcg/*.h",
"mach/"..e.arch.."/mcg/*.h",
}
}
local tables = mcgg {
name = e.name.."/tables",
srcs = { "mach/"..e.arch.."/mcg/table" }
}
return cprogram {
name = e.name,
srcs = {
"mach/proto/mcg/*.c",
"mach/"..e.arch.."/mcg/platform.c",
matching(filenamesof(tables), "%.c$")
},
deps = {
"h+emheaders",
"modules+headers",
"modules/src/alloc+lib",
"modules/src/data+lib",
"modules/src/em_code+lib_k",
"modules/src/em_data+lib",
"modules/src/flt_arith+lib",
"modules/src/idf+lib",
"modules/src/object+lib",
"modules/src/read_em+lib_kv",
"modules/src/string+lib",
"modules/src/system+lib",
"util/mcgg+lib",
headers,
tables, -- for .h file
}
}
end
)

160
mach/proto/mcg/data.c Normal file
View file

@ -0,0 +1,160 @@
#include "mcg.h"
#include <ctype.h>
#define IEEEFLOAT
#define FL_MSL_AT_LOW_ADDRESS 1
#define FL_MSW_AT_LOW_ADDRESS 1
#define FL_MSB_AT_LOW_ADDRESS 1
#include "con_float"
static struct symbol* pending;
void data_label(const char* label)
{
if (pending)
fatal("two consecutive data labels ('%s' and '%s')",
pending->name, label);
pending = symbol_get(label);
if (pending->is_defined)
fatal("label '%s' defined twice", pending->name);
pending->is_defined = true;
}
static const char* section_to_str(int section)
{
switch (section)
{
case SECTION_ROM: return ".rom";
case SECTION_DATA: return ".data";
case SECTION_BSS: return ".bss";
case SECTION_TEXT: return ".text";
default: return "unknown";
}
}
static void emit_header(int desired_section)
{
if (pending)
{
if (pending->section == SECTION_UNKNOWN)
pending->section = desired_section;
else if (pending->section != desired_section)
fatal("label '%s' can't change sections", pending->name);
fprintf(outputfile, "\n.sect %s\n", section_to_str(pending->section));
fprintf(outputfile, "%s:\n", platform_label(pending->name));
pending = NULL;
}
}
static void writehex(arith data, int size)
{
if (data < 0)
fprintf(outputfile, "-0x%0*lx", size*2, -data);
else
fprintf(outputfile, "0x%0*lx", size*2, data);
}
void data_int(arith data, size_t size, bool is_ro)
{
emit_header(is_ro ? SECTION_ROM : SECTION_DATA);
assert((size == 1) || (size == 2) || (size == 4) || (size == 8));
fprintf(outputfile, "\t.data%d ", size);
writehex(data, size);
fprintf(outputfile, "\n");
}
void data_float(const char* data, size_t size, bool is_ro)
{
unsigned char buffer[8];
int i;
emit_header(is_ro ? SECTION_ROM : SECTION_DATA);
assert((size == 4) || (size == 8));
i = float_cst(data, size, (char*) buffer);
if ((i != 0) && (i != 2)) /* 2 == overflow */
fatal("cannot parse floating point constant %s sz %d", data, size);
fprintf(outputfile, "\t!float %s sz %d\n", data, size);
fprintf(outputfile, "\t.data1 ");
writehex(buffer[0], 1);
for (i=1; i<size; i++)
{
fprintf(outputfile, ", ");
writehex(buffer[i], 1);
}
fprintf(outputfile, "\n");
}
static bool istext(c)
{
return isprint(c) && (c != '"');
}
void data_block(const uint8_t* data, size_t size, bool is_ro)
{
const uint8_t* start = data;
const uint8_t* end = data + size;
const uint8_t* p = data;
emit_header(is_ro ? SECTION_ROM : SECTION_DATA);
start = p = data;
while (p < end)
{
while ((p < end) && istext(*p))
p++;
if (start < p)
{
fprintf(outputfile, "\t.ascii \"");
while (start < p)
{
fprintf(outputfile, "%c", *start);
start++;
}
fprintf(outputfile, "\"\n");
}
while ((p < end) && !istext(*p))
p++;
if (start < p)
{
bool first = true;
fprintf(outputfile, "\t.data1 ");
while (start < p)
{
if (!first)
fprintf(outputfile, ", ");
writehex(*start, 1);
start++;
first = false;
}
fprintf(outputfile, "\n");
}
}
}
void data_offset(const char* label, arith offset, bool is_ro)
{
emit_header(is_ro ? SECTION_ROM : SECTION_DATA);
fprintf(outputfile, "\t.data%d %s+%lld\n",
EM_pointersize, platform_label(label), offset);
}
void data_bss(arith size, int init)
{
if (init != 0)
fatal("non-zero-initialised bss not supported");
emit_header(SECTION_BSS);
fprintf(outputfile, "\t.space %lld\n", size);
}
/* vim: set sw=4 ts=4 expandtab : */

210
mach/proto/mcg/graph.c Normal file
View file

@ -0,0 +1,210 @@
#include "mcg.h"
struct graph_data cfg;
struct dominance_data dominance;
static ARRAYOF(struct basicblock) pending;
static bool collect_outputs_cb(struct ir* ir, void* user)
{
struct basicblock* caller = user;
if (ir->opcode == IR_BLOCK)
{
array_appendu(&caller->nexts, ir->u.bvalue);
array_appendu(&ir->u.bvalue->prevs, caller);
pmap_add(&cfg.graph, caller, ir->u.bvalue);
}
return false;
}
static void update_block_pointers_from_ir(void)
{
int i, j;
for (i=0; i<current_proc->blocks.count; i++)
{
struct basicblock* bb = current_proc->blocks.item[i];
bb->prevs.count = bb->nexts.count = 0;
}
for (i=0; i<current_proc->blocks.count; i++)
{
struct basicblock* bb = current_proc->blocks.item[i];
for (j=0; j<bb->irs.count; j++)
ir_walk(bb->irs.item[j], collect_outputs_cb, bb);
}
for (i=0; i<current_proc->blocks.count; i++)
{
struct basicblock* bb = current_proc->blocks.item[i];
for (j=0; j<bb->nexts.count; j++)
{
tracef('D', "D: cfg graph %s -> %s\n",
bb->name,
bb->nexts.item[j]->name);
}
}
}
static void recursively_walk_cfg_graph(struct basicblock* bb)
{
int i;
if (array_contains(&cfg.postorder, bb) || array_contains(&pending, bb))
return;
array_appendu(&cfg.preorder, bb);
array_appendu(&pending, bb);
for (i=0; i<bb->nexts.count; i++)
recursively_walk_cfg_graph(bb->nexts.item[i]);
array_remove(&pending, bb);
bb->order = cfg.postorder.count;
array_appendu(&cfg.postorder, bb);
}
static void walk_cfg_graph(void)
{
int i;
cfg.preorder.count = 0;
cfg.postorder.count = 0;
pending.count = 0;
recursively_walk_cfg_graph(cfg.entry);
for (i=0; i<cfg.preorder.count; i++)
{
tracef('G', "G: cfg preorder: %s\n",
cfg.preorder.item[i]->name);
}
}
static struct basicblock* intersect(struct basicblock* p1, struct basicblock* p2)
{
while (p1 != p2)
{
while (p1->order < p2->order)
p1 = pmap_findleft(&dominance.graph, p1);
while (p2->order < p1->order)
p2 = pmap_findleft(&dominance.graph, p2);
}
return p1;
}
static void calculate_dominance_graph(void)
{
/* This is the algorithm described here:
*
* Cooper, Keith D., Timothy J. Harvey, and Ken Kennedy.
* "A simple, fast dominance algorithm."
* Software Practice & Experience 4.1-10 (2001): 1-8.
*
* https://www.cs.rice.edu/~keith/EMBED/dom.pdf
*/
int i, j;
bool changed;
dominance.graph.count = 0;
/* The entry block dominates itself. */
pmap_put(&dominance.graph, cfg.entry, cfg.entry);
do
{
changed = false;
for (i = cfg.postorder.count-2; i >= 0; i--)
{
struct basicblock* b = cfg.postorder.item[i];
struct basicblock* new_idom = NULL;
for (j=0; j<b->prevs.count; j++)
{
struct basicblock* p = b->prevs.item[j];
/* Skip unprocessed blocks. */
if (!pmap_findleft(&dominance.graph, p))
continue;
if (!new_idom)
new_idom = p;
else if (pmap_findleft(&dominance.graph, p))
new_idom = intersect(p, new_idom);
}
if (pmap_findleft(&dominance.graph, b) != new_idom)
{
pmap_put(&dominance.graph, b, new_idom);
changed = true;
}
}
}
while (changed);
for (i=0; i<dominance.graph.count; i++)
{
tracef('G', "G: dominance graph: %s -> %s\n",
dominance.graph.item[i].right->name,
dominance.graph.item[i].left->name);
}
}
static void recursively_walk_dominance_graph(struct basicblock* bb)
{
int i;
if (array_contains(&dominance.postorder, bb) || array_contains(&pending, bb))
return;
array_appendu(&dominance.preorder, bb);
array_appendu(&pending, bb);
for (i=0; i<dominance.graph.count; i++)
if (dominance.graph.item[i].right == bb)
recursively_walk_dominance_graph(dominance.graph.item[i].left);
array_remove(&pending, bb);
array_appendu(&dominance.postorder, bb);
}
static void walk_dominance_graph(void)
{
int i;
dominance.preorder.count = 0;
dominance.postorder.count = 0;
pending.count = 0;
recursively_walk_dominance_graph(cfg.entry);
for (i=0; i<dominance.preorder.count; i++)
{
tracef('G', "G: dominance preorder: %s\n",
dominance.preorder.item[i]->name);
}
}
void update_graph_data(void)
{
cfg.entry = current_proc->blocks.item[0];
cfg.graph.count = 0;
update_block_pointers_from_ir();
walk_cfg_graph();
assert(cfg.postorder.count == current_proc->blocks.count);
assert(cfg.preorder.count == current_proc->blocks.count);
calculate_dominance_graph();
walk_dominance_graph();
assert(dominance.postorder.count == dominance.graph.count);
assert(dominance.preorder.count == dominance.graph.count);
}
/* vim: set sw=4 ts=4 expandtab : */

27
mach/proto/mcg/graph.h Normal file
View file

@ -0,0 +1,27 @@
#ifndef GRAPH_H
#define GRAPH_H
struct graph_data
{
struct basicblock* entry;
PMAPOF(struct basicblock, struct basicblock) graph;
ARRAYOF(struct basicblock) preorder;
ARRAYOF(struct basicblock) postorder;
};
struct dominance_data
{
PMAPOF(struct basicblock, struct basicblock) graph;
ARRAYOF(struct basicblock) preorder;
ARRAYOF(struct basicblock) postorder;
};
extern struct graph_data cfg;
extern struct dominance_data dominance;
extern void update_graph_data(void);
#endif
/* vim: set sw=4 ts=4 expandtab : */

Some files were not shown because too many files have changed in this diff Show more