Skip to content

Commit

Permalink
feat! Add paniccing integer division ops
Browse files Browse the repository at this point in the history
  • Loading branch information
doug-q committed Oct 31, 2023
1 parent 46d5017 commit 90ae4bf
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 0 deletions.
6 changes: 6 additions & 0 deletions specification/hugr.md
Original file line number Diff line number Diff line change
Expand Up @@ -1660,11 +1660,17 @@ Other operations:
| `ineg<N>` | `int<N>` | `int<N>` | negation modulo 2^N (signed and unsigned versions are the same op) |
| `imul<N>` | `int<N>`, `int<N>` | `int<N>` | multiplication modulo 2^N (signed and unsigned versions are the same op) |
| `idivmod_u<N,M>`( \* ) | `int<N>`, `int<M>` | `Sum((int<N>, int<M>), ErrorType)` | given unsigned integers 0 \<= n \< 2^N, 0 \<= m \< 2^M, generates unsigned q, r where q\*m+r=n, 0\<=r\<m (m=0 is an error) |
| `idivmod2_u<N,M>`( \* ) | `int<N>`, `int<M>` | `(int<N>, int<M>)` | given unsigned integers 0 \<= n \< 2^N, 0 \<= m \< 2^M, generates unsigned q, r where q\*m+r=n, 0\<=r\<m (m=0 will call panic) |
| `idivmod_s<N,M>`( \* ) | `int<N>`, `int<M>` | `Sum((int<N>, int<M>), ErrorType)` | given signed integer -2^{N-1} \<= n \< 2^{N-1} and unsigned 0 \<= m \< 2^M, generates signed q and unsigned r where q\*m+r=n, 0\<=r\<m (m=0 is an error) |
| `idivmod_s<N,M>`( \* ) | `int<N>`, `int<M>` | `(int<N>, int<M>)` | given signed integer -2^{N-1} \<= n \< 2^{N-1} and unsigned 0 \<= m \< 2^M, generates signed q and unsigned r where q\*m+r=n, 0\<=r\<m (m=0 will call panic) |
| `idiv_u<N,M>` | `int<N>`, `int<M>` | `Sum(int<N>, ErrorType)` | as `idivmod_u` but discarding the second output |
| `idiv2_u<N,M>` | `int<N>`, `int<M>` | `int<N>` | as `idivmod2_u` but discarding the second output |
| `imod_u<N,M>` | `int<N>`, `int<M>` | `Sum(int<M>, ErrorType)` | as `idivmod_u` but discarding the first output |
| `imod2_u<N,M>` | `int<N>`, `int<M>` | `int<M>` | as `idivmod2_u` but discarding the first output |
| `idiv_s<N,M>`( \* ) | `int<N>`, `int<M>` | `Sum(int<N>, ErrorType)` | as `idivmod_s` but discarding the second output |
| `idiv2_s<N,M>`( \* ) | `int<N>`, `int<M>` | `int<N>` | as `idivmod2_s` but discarding the second output |
| `imod_s<N,M>`( \* ) | `int<N>`, `int<M>` | `Sum(int<M>, ErrorType)` | as `idivmod_s` but discarding the first output |
| `imod2_s<N,M>`( \* ) | `int<N>`, `int<M>` | `int<M>` | as `idivmod2_s` but discarding the first output |
| `iabs<N>` | `int<N>` | `int<N>` | convert signed to unsigned by taking absolute value |
| `iand<N>` | `int<N>`, `int<N>` | `int<N>` | bitwise AND |
| `ior<N>` | `int<N>`, `int<N>` | `int<N>` | bitwise OR |
Expand Down
77 changes: 77 additions & 0 deletions src/std_extensions/arithmetic/int_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,15 @@ fn idivmod_sig(arg_values: &[TypeArg]) -> Result<FunctionType, SignatureError> {
))
}

fn idivmod2_sig(arg_values: &[TypeArg]) -> Result<FunctionType, SignatureError> {
let [arg0, arg1] = collect_array(arg_values);
let intpair: TypeRow = vec![int_type(arg0.clone()), int_type(arg1.clone())].into();
Ok(FunctionType::new(
intpair.clone(),
vec![Type::new_tuple(intpair)],
))
}

fn idiv_sig(arg_values: &[TypeArg]) -> Result<FunctionType, SignatureError> {
let [arg0, arg1] = collect_array(arg_values);
Ok(FunctionType::new(
Expand All @@ -95,6 +104,14 @@ fn idiv_sig(arg_values: &[TypeArg]) -> Result<FunctionType, SignatureError> {
))
}

fn idiv2_sig(arg_values: &[TypeArg]) -> Result<FunctionType, SignatureError> {
let [arg0, arg1] = collect_array(arg_values);
Ok(FunctionType::new(
vec![int_type(arg0.clone()), int_type(arg1.clone())],
vec![int_type(arg0.clone())],
))
}

fn imod_sig(arg_values: &[TypeArg]) -> Result<FunctionType, SignatureError> {
let [arg0, arg1] = collect_array(arg_values);
Ok(FunctionType::new(
Expand All @@ -103,6 +120,14 @@ fn imod_sig(arg_values: &[TypeArg]) -> Result<FunctionType, SignatureError> {
))
}

fn imod2_sig(arg_values: &[TypeArg]) -> Result<FunctionType, SignatureError> {
let [arg0, arg1] = collect_array(arg_values);
Ok(FunctionType::new(
vec![int_type(arg0.clone()), int_type(arg1.clone())],
vec![int_type(arg1.clone())],
))
}

fn ish_sig(arg_values: &[TypeArg]) -> Result<FunctionType, SignatureError> {
let [arg0, arg1] = collect_array(arg_values);
Ok(FunctionType::new(
Expand Down Expand Up @@ -321,6 +346,16 @@ pub fn extension() -> Extension {
idivmod_sig,
)
.unwrap();
extension
.add_op_custom_sig_simple(
"idivmod2_u".into(),
"given unsigned integers 0 <= n < 2^N, 0 <= m < 2^M, generates unsigned q, r where \
q*m+r=n, 0<=r<m (m=0 will call panic)"
.to_owned(),
vec![LOG_WIDTH_TYPE_PARAM, LOG_WIDTH_TYPE_PARAM],
idivmod2_sig,
)
.unwrap();
extension
.add_op_custom_sig_simple(
"idivmod_s".into(),
Expand All @@ -331,6 +366,16 @@ pub fn extension() -> Extension {
idivmod_sig,
)
.unwrap();
extension
.add_op_custom_sig_simple(
"idivmod2_s".into(),
"given signed integer -2^{N-1} <= n < 2^{N-1} and unsigned 0 <= m < 2^M, generates \
signed q and unsigned r where q*m+r=n, 0<=r<m (m=0 will call panic)"
.to_owned(),
vec![LOG_WIDTH_TYPE_PARAM, LOG_WIDTH_TYPE_PARAM],
idivmod2_sig,
)
.unwrap();
extension
.add_op_custom_sig_simple(
"idiv_u".into(),
Expand All @@ -339,6 +384,14 @@ pub fn extension() -> Extension {
idiv_sig,
)
.unwrap();
extension
.add_op_custom_sig_simple(
"idiv2_u".into(),
"as idivmod2_u but discarding the second output".to_owned(),
vec![LOG_WIDTH_TYPE_PARAM, LOG_WIDTH_TYPE_PARAM],
idiv2_sig,
)
.unwrap();
extension
.add_op_custom_sig_simple(
"imod_u".into(),
Expand All @@ -347,6 +400,14 @@ pub fn extension() -> Extension {
idiv_sig,
)
.unwrap();
extension
.add_op_custom_sig_simple(
"imod2_u".into(),
"as idivmod2_u but discarding the first output".to_owned(),
vec![LOG_WIDTH_TYPE_PARAM, LOG_WIDTH_TYPE_PARAM],
idiv2_sig,
)
.unwrap();
extension
.add_op_custom_sig_simple(
"idiv_s".into(),
Expand All @@ -355,6 +416,14 @@ pub fn extension() -> Extension {
imod_sig,
)
.unwrap();
extension
.add_op_custom_sig_simple(
"idiv2_s".into(),
"as idivmod2_s but discarding the second output".to_owned(),
vec![LOG_WIDTH_TYPE_PARAM, LOG_WIDTH_TYPE_PARAM],
imod2_sig,
)
.unwrap();
extension
.add_op_custom_sig_simple(
"imod_s".into(),
Expand All @@ -363,6 +432,14 @@ pub fn extension() -> Extension {
imod_sig,
)
.unwrap();
extension
.add_op_custom_sig_simple(
"imod2_s".into(),
"as idivmod2_s but discarding the first output".to_owned(),
vec![LOG_WIDTH_TYPE_PARAM, LOG_WIDTH_TYPE_PARAM],
imod2_sig,
)
.unwrap();
extension
.add_op_custom_sig_simple(
"iabs".into(),
Expand Down

0 comments on commit 90ae4bf

Please sign in to comment.