162306a36Sopenharmony_ci#!/usr/bin/perl -w
262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause
362306a36Sopenharmony_ci# Copyright (C) 2019--2020 Intel Corporation
462306a36Sopenharmony_ci
562306a36Sopenharmony_ciuse Getopt::Long qw(:config no_ignore_case);
662306a36Sopenharmony_ciuse File::Basename;
762306a36Sopenharmony_ci
862306a36Sopenharmony_cimy $ccsregs = "ccs-regs.asc";
962306a36Sopenharmony_cimy $header;
1062306a36Sopenharmony_cimy $regarray;
1162306a36Sopenharmony_cimy $limitc;
1262306a36Sopenharmony_cimy $limith;
1362306a36Sopenharmony_cimy $kernel;
1462306a36Sopenharmony_cimy $help;
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ciGetOptions("ccsregs|c=s" => \$ccsregs,
1762306a36Sopenharmony_ci	   "header|e=s" => \$header,
1862306a36Sopenharmony_ci	   "regarray|r=s" => \$regarray,
1962306a36Sopenharmony_ci	   "limitc|l=s" => \$limitc,
2062306a36Sopenharmony_ci	   "limith|L=s" => \$limith,
2162306a36Sopenharmony_ci	   "kernel|k" => \$kernel,
2262306a36Sopenharmony_ci	   "help|h" => \$help) or die "can't parse options";
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci$help = 1 if ! defined $header || ! defined $limitc || ! defined $limith;
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ciif (defined $help) {
2762306a36Sopenharmony_ci	print <<EOH
2862306a36Sopenharmony_ci$0 - Create CCS register definitions for C
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ciusage: $0 -c ccs-regs.asc -e header -r regarray -l limit-c -L limit-header [-k]
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	-c ccs register file
3362306a36Sopenharmony_ci	-e header file name
3462306a36Sopenharmony_ci	-r register description array file name
3562306a36Sopenharmony_ci	-l limit and capability array file name
3662306a36Sopenharmony_ci	-L limit and capability header file name
3762306a36Sopenharmony_ci	-k generate files for kernel space consumption
3862306a36Sopenharmony_ciEOH
3962306a36Sopenharmony_ci	  ;
4062306a36Sopenharmony_ci	exit 0;
4162306a36Sopenharmony_ci}
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_cimy $lh_hdr = ! defined $kernel
4462306a36Sopenharmony_ci	? '#include "ccs-os.h"' . "\n"
4562306a36Sopenharmony_ci	: "#include <linux/bits.h>\n#include <linux/types.h>\n";
4662306a36Sopenharmony_cimy $uint32_t = ! defined $kernel ? 'uint32_t' : 'u32';
4762306a36Sopenharmony_cimy $uint16_t = ! defined $kernel ? 'uint16_t' : 'u16';
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ciopen(my $R, "< $ccsregs") or die "can't open $ccsregs";
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ciopen(my $H, "> $header") or die "can't open $header";
5262306a36Sopenharmony_cimy $A;
5362306a36Sopenharmony_ciif (defined $regarray) {
5462306a36Sopenharmony_ci	open($A, "> $regarray") or die "can't open $regarray";
5562306a36Sopenharmony_ci}
5662306a36Sopenharmony_ciopen(my $LC, "> $limitc") or die "can't open $limitc";
5762306a36Sopenharmony_ciopen(my $LH, "> $limith") or die "can't open $limith";
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_cimy %this;
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_cisub is_limit_reg($) {
6262306a36Sopenharmony_ci	my $addr = hex $_[0];
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci	return 0 if $addr < 0x40; # weed out status registers
6562306a36Sopenharmony_ci	return 0 if $addr >= 0x100 && $addr < 0xfff; # weed out configuration registers
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci	return 1;
6862306a36Sopenharmony_ci}
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_cimy $uc_header = basename uc $header;
7162306a36Sopenharmony_ci$uc_header =~ s/[^A-Z0-9]/_/g;
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_cimy $copyright = "/* Copyright (C) 2019--2020 Intel Corporation */\n";
7462306a36Sopenharmony_cimy $license = "SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause";
7562306a36Sopenharmony_cimy $note = "/*\n * Generated by $0;\n * do not modify.\n */\n";
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_cifor my $fh ($A, $LC) {
7862306a36Sopenharmony_ci	print $fh "// $license\n$copyright$note\n" if defined $fh;
7962306a36Sopenharmony_ci}
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_cifor my $fh ($H, $LH) {
8262306a36Sopenharmony_ci	print $fh "/* $license */\n$copyright$note\n";
8362306a36Sopenharmony_ci}
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_cisub bit_def($) {
8662306a36Sopenharmony_ci	my $bit = shift @_;
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci	return "BIT($bit)" if defined $kernel;
8962306a36Sopenharmony_ci	return "(1U << $bit)" if $bit =~ /^[a-zA-Z0-9_]+$/;
9062306a36Sopenharmony_ci	return "(1U << ($bit))";
9162306a36Sopenharmony_ci}
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ciprint $H <<EOF
9462306a36Sopenharmony_ci#ifndef __${uc_header}__
9562306a36Sopenharmony_ci#define __${uc_header}__
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ciEOF
9862306a36Sopenharmony_ci  ;
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ciprint $H "#include <linux/bits.h>\n\n" if defined $kernel;
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ciprint $H <<EOF
10362306a36Sopenharmony_ci#define CCS_FL_BASE		16
10462306a36Sopenharmony_ciEOF
10562306a36Sopenharmony_ci  ;
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ciprint $H "#define CCS_FL_16BIT		" . bit_def("CCS_FL_BASE") . "\n";
10862306a36Sopenharmony_ciprint $H "#define CCS_FL_32BIT		" . bit_def("CCS_FL_BASE + 1") . "\n";
10962306a36Sopenharmony_ciprint $H "#define CCS_FL_FLOAT_IREAL	" . bit_def("CCS_FL_BASE + 2") . "\n";
11062306a36Sopenharmony_ciprint $H "#define CCS_FL_IREAL		" . bit_def("CCS_FL_BASE + 3") . "\n";
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ciprint $H <<EOF
11362306a36Sopenharmony_ci#define CCS_R_ADDR(r)		((r) & 0xffff)
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ciEOF
11662306a36Sopenharmony_ci  ;
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ciprint $A <<EOF
11962306a36Sopenharmony_ci#include <stdint.h>
12062306a36Sopenharmony_ci#include <stdio.h>
12162306a36Sopenharmony_ci#include "ccs-extra.h"
12262306a36Sopenharmony_ci#include "ccs-regs.h"
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ciEOF
12562306a36Sopenharmony_ci	if defined $A;
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_cimy $uc_limith = basename uc $limith;
12862306a36Sopenharmony_ci$uc_limith =~ s/[^A-Z0-9]/_/g;
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ciprint $LH <<EOF
13162306a36Sopenharmony_ci#ifndef __${uc_limith}__
13262306a36Sopenharmony_ci#define __${uc_limith}__
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci$lh_hdr
13562306a36Sopenharmony_cistruct ccs_limit {
13662306a36Sopenharmony_ci	$uint32_t reg;
13762306a36Sopenharmony_ci	$uint16_t size;
13862306a36Sopenharmony_ci	$uint16_t flags;
13962306a36Sopenharmony_ci	const char *name;
14062306a36Sopenharmony_ci};
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ciEOF
14362306a36Sopenharmony_ci  ;
14462306a36Sopenharmony_ciprint $LH "#define CCS_L_FL_SAME_REG	" . bit_def(0) . "\n\n";
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ciprint $LH <<EOF
14762306a36Sopenharmony_ciextern const struct ccs_limit ccs_limits[];
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ciEOF
15062306a36Sopenharmony_ci  ;
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ciprint $LC <<EOF
15362306a36Sopenharmony_ci#include "ccs-limits.h"
15462306a36Sopenharmony_ci#include "ccs-regs.h"
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ciconst struct ccs_limit ccs_limits[] = {
15762306a36Sopenharmony_ciEOF
15862306a36Sopenharmony_ci  ;
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_cimy $limitcount = 0;
16162306a36Sopenharmony_cimy $argdescs;
16262306a36Sopenharmony_cimy $reglist = "const struct ccs_reg_desc ccs_reg_desc[] = {\n";
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_cisub name_split($$) {
16562306a36Sopenharmony_ci	my ($name, $addr) = @_;
16662306a36Sopenharmony_ci	my $args;
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci	$name =~ /([^\(]+?)(\(.*)/;
16962306a36Sopenharmony_ci	($name, $args) = ($1, $2);
17062306a36Sopenharmony_ci	$args = [split /,\s*/, $args];
17162306a36Sopenharmony_ci	foreach my $t (@$args) {
17262306a36Sopenharmony_ci		$t =~ s/[\(\)]//g;
17362306a36Sopenharmony_ci		$t =~ s/\//\\\//g;
17462306a36Sopenharmony_ci	}
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci	return ($name, $addr, $args);
17762306a36Sopenharmony_ci}
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_cisub tabconv($) {
18062306a36Sopenharmony_ci	$_ = shift;
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci	my @l = split "\n", $_;
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci	map {
18562306a36Sopenharmony_ci		s/ {8,8}/\t/g;
18662306a36Sopenharmony_ci		s/\t\K +//;
18762306a36Sopenharmony_ci	} @l;
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci	return (join "\n", @l) . "\n";
19062306a36Sopenharmony_ci}
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_cisub elem_size(@) {
19362306a36Sopenharmony_ci	my @flags = @_;
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci	return 2 if grep /^16$/, @flags;
19662306a36Sopenharmony_ci	return 4 if grep /^32$/, @flags;
19762306a36Sopenharmony_ci	return 1;
19862306a36Sopenharmony_ci}
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_cisub arr_size($) {
20162306a36Sopenharmony_ci	my $this = $_[0];
20262306a36Sopenharmony_ci	my $size = $this->{elsize};
20362306a36Sopenharmony_ci	my $h = $this->{argparams};
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci	foreach my $arg (@{$this->{args}}) {
20662306a36Sopenharmony_ci		my $apref = $h->{$arg};
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_ci		$size *= $apref->{max} - $apref->{min} + 1;
20962306a36Sopenharmony_ci	}
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci	return $size;
21262306a36Sopenharmony_ci}
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_cisub print_args($$$) {
21562306a36Sopenharmony_ci	my ($this, $postfix, $is_same_reg) = @_;
21662306a36Sopenharmony_ci	my ($args, $argparams, $name) =
21762306a36Sopenharmony_ci	  ($this->{args}, $this->{argparams}, $this->{name});
21862306a36Sopenharmony_ci	my $varname = "ccs_reg_arg_" . (lc $name) . $postfix;
21962306a36Sopenharmony_ci	my @mins;
22062306a36Sopenharmony_ci	my @sorted_args = @{$this->{sorted_args}};
22162306a36Sopenharmony_ci	my $lim_arg;
22262306a36Sopenharmony_ci	my $size = arr_size($this);
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci	$argdescs .= "static const struct ccs_reg_arg " . $varname . "[] = {\n";
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci	foreach my $sorted_arg (@sorted_args) {
22762306a36Sopenharmony_ci		push @mins, $argparams->{$sorted_arg}->{min};
22862306a36Sopenharmony_ci	}
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci	foreach my $sorted_arg (@sorted_args) {
23162306a36Sopenharmony_ci		my $h = $argparams->{$sorted_arg};
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci		$argdescs .= "\t{ \"$sorted_arg\", $h->{min}, $h->{max}, $h->{elsize} },\n";
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ci		$lim_arg .= defined $lim_arg ? ", $h->{min}" : "$h->{min}";
23662306a36Sopenharmony_ci	}
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci	$argdescs .= "};\n\n";
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci	$reglist .= "\t{ CCS_R_" . (uc $name) . "(" . (join ",", (@mins)) .
24162306a36Sopenharmony_ci	  "), $size, sizeof($varname) / sizeof(*$varname)," .
24262306a36Sopenharmony_ci	    " \"" . (lc $name) . "\", $varname },\n";
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_ci	print $LC tabconv sprintf "\t{ CCS_R_" . (uc $name) . "($lim_arg), " .
24562306a36Sopenharmony_ci	  $size . ", " . ($is_same_reg ? "CCS_L_FL_SAME_REG" : "0") .
24662306a36Sopenharmony_ci	    ", \"$name" . (defined $this->{discontig} ? " $lim_arg" : "") . "\" },\n"
24762306a36Sopenharmony_ci	      if is_limit_reg $this->{base_addr};
24862306a36Sopenharmony_ci}
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_cimy $hdr_data;
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_ciwhile (<$R>) {
25362306a36Sopenharmony_ci	chop;
25462306a36Sopenharmony_ci	s/^\s*//;
25562306a36Sopenharmony_ci	next if /^[#;]/ || /^$/;
25662306a36Sopenharmony_ci	if (s/^-\s*//) {
25762306a36Sopenharmony_ci		if (s/^b\s*//) {
25862306a36Sopenharmony_ci			my ($bit, $addr) = split /\t+/;
25962306a36Sopenharmony_ci			$bit = uc $bit;
26062306a36Sopenharmony_ci			$hdr_data .= sprintf "#define %-62s %s", "CCS_" . (uc ${this{name}}) ."_$bit", bit_def($addr) . "\n";
26162306a36Sopenharmony_ci		} elsif (s/^f\s*//) {
26262306a36Sopenharmony_ci			s/[,\.-]/_/g;
26362306a36Sopenharmony_ci			my @a = split /\s+/;
26462306a36Sopenharmony_ci			my ($msb, $lsb, $this_field) = reverse @a;
26562306a36Sopenharmony_ci		        @a = ( { "name" => "SHIFT", "addr" => $lsb, "fmt" => "%uU", },
26662306a36Sopenharmony_ci			       { "name" => "MASK", "addr" => (1 << ($msb + 1)) - 1 - ((1 << $lsb) - 1), "fmt" => "0x%" . join(".", ($this{"elsize"} >> 2) x 2) . "x" } );
26762306a36Sopenharmony_ci			$this{"field"} = $this_field;
26862306a36Sopenharmony_ci			foreach my $ar (@a) {
26962306a36Sopenharmony_ci				#print $ar->{fmt}."\n";
27062306a36Sopenharmony_ci				$hdr_data .= sprintf "#define %-62s " . $ar->{"fmt"} . "\n", "CCS_" . (uc $this{"name"}) . (defined $this_field ? "_" . uc $this_field : "") . "_" . $ar->{"name"}, $ar->{"addr"} . "\n";
27162306a36Sopenharmony_ci			}
27262306a36Sopenharmony_ci		} elsif (s/^e\s*//) {
27362306a36Sopenharmony_ci			s/[,\.-]/_/g;
27462306a36Sopenharmony_ci			my ($enum, $addr) = split /\s+/;
27562306a36Sopenharmony_ci			$enum = uc $enum;
27662306a36Sopenharmony_ci			$hdr_data .= sprintf "#define %-62s %s", "CCS_" . (uc ${this{name}}) . (defined $this{"field"} ? "_" . uc $this{"field"} : "") ."_$enum", $addr . ($addr =~ /0x/i ? "" : "U") . "\n";
27762306a36Sopenharmony_ci		} elsif (s/^l\s*//) {
27862306a36Sopenharmony_ci			my ($arg, $min, $max, $elsize, @discontig) = split /\s+/;
27962306a36Sopenharmony_ci			my $size;
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci			foreach my $num ($min, $max) {
28262306a36Sopenharmony_ci				$num = hex $num if $num =~ /0x/i;
28362306a36Sopenharmony_ci			}
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_ci			$hdr_data .= sprintf "#define %-62s %s", "CCS_LIM_" . (uc ${this{name}} . "_MIN_$arg"), $min . ($min =~ /0x/i ? "" : "U") . "\n";
28662306a36Sopenharmony_ci			$hdr_data .= sprintf "#define %-62s %s", "CCS_LIM_" . (uc ${this{name}} . "_MAX_$arg"), $max . ($max =~ /0x/i ? "" : "U") . "\n";
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci			my $h = $this{argparams};
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_ci			$h->{$arg} = { "min" => $min,
29162306a36Sopenharmony_ci				       "max" => $max,
29262306a36Sopenharmony_ci				       "elsize" => $elsize =~ /^0x/ ? hex $elsize : $elsize,
29362306a36Sopenharmony_ci				       "discontig" => \@discontig };
29462306a36Sopenharmony_ci
29562306a36Sopenharmony_ci			$this{discontig} = $arg if @discontig;
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ci			next if $#{$this{args}} + 1 != scalar keys %{$this{argparams}};
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci			my $reg_formula = "($this{addr}";
30062306a36Sopenharmony_ci			my $lim_formula;
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci			foreach my $arg (@{$this{args}}) {
30362306a36Sopenharmony_ci				my $d = $h->{$arg}->{discontig};
30462306a36Sopenharmony_ci				my $times = $h->{$arg}->{elsize} != 1 ?
30562306a36Sopenharmony_ci				  " * " . $h->{$arg}->{elsize} : "";
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_ci				if (@$d) {
30862306a36Sopenharmony_ci					my ($lim, $offset) = split /,/, $d->[0];
30962306a36Sopenharmony_ci
31062306a36Sopenharmony_ci					$reg_formula .= " + (($arg) < $lim ? ($arg)$times : $offset + (($arg) - $lim)$times)";
31162306a36Sopenharmony_ci				} else {
31262306a36Sopenharmony_ci					$reg_formula .= " + ($arg)$times";
31362306a36Sopenharmony_ci				}
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci				$lim_formula .= (defined $lim_formula ? " + " : "") . "($arg)$times";
31662306a36Sopenharmony_ci			}
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci			$reg_formula .= ")\n";
31962306a36Sopenharmony_ci			$lim_formula =~ s/^\(([a-z0-9]+)\)$/$1/i;
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci			print $H tabconv sprintf("#define %-62s %s", "CCS_R_" . (uc $this{name}) .
32262306a36Sopenharmony_ci			  $this{arglist}, $reg_formula);
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci			print $H tabconv $hdr_data;
32562306a36Sopenharmony_ci			undef $hdr_data;
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_ci			# Sort arguments in descending order by size
32862306a36Sopenharmony_ci			@{$this{sorted_args}} = sort {
32962306a36Sopenharmony_ci				$h->{$a}->{elsize} <= $h->{$b}->{elsize}
33062306a36Sopenharmony_ci			} @{$this{args}};
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_ci			if (defined $this{discontig}) {
33362306a36Sopenharmony_ci				my $da = $this{argparams}->{$this{discontig}};
33462306a36Sopenharmony_ci				my ($first_discontig) = split /,/, $da->{discontig}->[0];
33562306a36Sopenharmony_ci				my $max = $da->{max};
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_ci				$da->{max} = $first_discontig - 1;
33862306a36Sopenharmony_ci				print_args(\%this, "", 0);
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci				$da->{min} = $da->{max} + 1;
34162306a36Sopenharmony_ci				$da->{max} = $max;
34262306a36Sopenharmony_ci				print_args(\%this, $first_discontig, 1);
34362306a36Sopenharmony_ci			} else {
34462306a36Sopenharmony_ci				print_args(\%this, "", 0);
34562306a36Sopenharmony_ci			}
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci			next unless is_limit_reg $this{base_addr};
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci			print $LH tabconv sprintf "#define %-63s%s\n",
35062306a36Sopenharmony_ci			  "CCS_L_" . (uc $this{name}) . "_OFFSET(" .
35162306a36Sopenharmony_ci			    (join ", ", @{$this{args}}) . ")", "($lim_formula)";
35262306a36Sopenharmony_ci		}
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci		if (! @{$this{args}}) {
35562306a36Sopenharmony_ci			print $H tabconv($hdr_data);
35662306a36Sopenharmony_ci			undef $hdr_data;
35762306a36Sopenharmony_ci		}
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ci		next;
36062306a36Sopenharmony_ci	}
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_ci	my ($name, $addr, @flags) = split /\t+/, $_;
36362306a36Sopenharmony_ci	my $args = [];
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci	my $sp;
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_ci	($name, $addr, $args) = name_split($name, $addr) if /\(.*\)/;
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci	$name =~ s/[,\.-]/_/g;
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ci	my $flagstring = "";
37262306a36Sopenharmony_ci	my $size = elem_size(@flags);
37362306a36Sopenharmony_ci	$flagstring .= "| CCS_FL_16BIT " if $size eq "2";
37462306a36Sopenharmony_ci	$flagstring .= "| CCS_FL_32BIT " if $size eq "4";
37562306a36Sopenharmony_ci	$flagstring .= "| CCS_FL_FLOAT_IREAL " if grep /^float_ireal$/, @flags;
37662306a36Sopenharmony_ci	$flagstring .= "| CCS_FL_IREAL " if grep /^ireal$/, @flags;
37762306a36Sopenharmony_ci	$flagstring =~ s/^\| //;
37862306a36Sopenharmony_ci	$flagstring =~ s/ $//;
37962306a36Sopenharmony_ci	$flagstring = "($flagstring)" if $flagstring =~ /\|/;
38062306a36Sopenharmony_ci	my $base_addr = $addr;
38162306a36Sopenharmony_ci	$addr = "($addr | $flagstring)" if $flagstring ne "";
38262306a36Sopenharmony_ci
38362306a36Sopenharmony_ci	my $arglist = @$args ? "(" . (join ", ", @$args) . ")" : "";
38462306a36Sopenharmony_ci	$hdr_data .= sprintf "#define %-62s %s\n", "CCS_R_" . (uc $name), $addr
38562306a36Sopenharmony_ci	  if !@$args;
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_ci	$name =~ s/\(.*//;
38862306a36Sopenharmony_ci
38962306a36Sopenharmony_ci	%this = ( name => $name,
39062306a36Sopenharmony_ci		  addr => $addr,
39162306a36Sopenharmony_ci		  base_addr => $base_addr,
39262306a36Sopenharmony_ci		  argparams => {},
39362306a36Sopenharmony_ci		  args => $args,
39462306a36Sopenharmony_ci		  arglist => $arglist,
39562306a36Sopenharmony_ci		  elsize => $size,
39662306a36Sopenharmony_ci		);
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_ci	if (!@$args) {
39962306a36Sopenharmony_ci		$reglist .= "\t{ CCS_R_" . (uc $name) . ", 1,  0, \"" . (lc $name) . "\", NULL },\n";
40062306a36Sopenharmony_ci		print $H tabconv $hdr_data;
40162306a36Sopenharmony_ci		undef $hdr_data;
40262306a36Sopenharmony_ci
40362306a36Sopenharmony_ci		print $LC tabconv sprintf "\t{ CCS_R_" . (uc $name) . ", " .
40462306a36Sopenharmony_ci		  $this{elsize} . ", 0, \"$name\" },\n"
40562306a36Sopenharmony_ci		    if is_limit_reg $this{base_addr};
40662306a36Sopenharmony_ci	}
40762306a36Sopenharmony_ci
40862306a36Sopenharmony_ci	print $LH tabconv sprintf "#define %-63s%s\n",
40962306a36Sopenharmony_ci	  "CCS_L_" . (uc $this{name}), $limitcount++
41062306a36Sopenharmony_ci	    if is_limit_reg $this{base_addr};
41162306a36Sopenharmony_ci}
41262306a36Sopenharmony_ci
41362306a36Sopenharmony_ciif (defined $A) {
41462306a36Sopenharmony_ci	print $A $argdescs, $reglist;
41562306a36Sopenharmony_ci
41662306a36Sopenharmony_ci	print $A "\t{ 0 }\n";
41762306a36Sopenharmony_ci
41862306a36Sopenharmony_ci	print $A "};\n";
41962306a36Sopenharmony_ci}
42062306a36Sopenharmony_ci
42162306a36Sopenharmony_ciprint $H "\n#endif /* __${uc_header}__ */\n";
42262306a36Sopenharmony_ci
42362306a36Sopenharmony_ciprint $LH tabconv sprintf "#define %-63s%s\n", "CCS_L_LAST", $limitcount;
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_ciprint $LH "\n#endif /* __${uc_limith}__ */\n";
42662306a36Sopenharmony_ci
42762306a36Sopenharmony_ciprint $LC "\t{ 0 } /* Guardian */\n";
42862306a36Sopenharmony_ciprint $LC "};\n";
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_ciclose($R);
43162306a36Sopenharmony_ciclose($H);
43262306a36Sopenharmony_ciclose($A) if defined $A;
43362306a36Sopenharmony_ciclose($LC);
43462306a36Sopenharmony_ciclose($LH);
435